linux/drivers/soc/mediatek/mtk-infracfg.c
Alyssa Rosenzweig dcfd519256 soc: mediatek: mtk-infracfg: Disable ACP on MT8192
MT8192 contains an experimental Accelerator Coherency Port
implementation, which does not work correctly but was unintentionally
enabled by default. For correct operation of the GPU, we must set a
chicken bit disabling ACP on MT8192.

Adapted from the following downstream change to the out-of-tree, legacy
Mali GPU driver:

https://chromium-review.googlesource.com/c/chromiumos/third_party/kernel/+/2781271/5

Note this change is required for both Panfrost and the legacy kernel
driver.

Co-developed-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
Signed-off-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Cc: Nick Fan <Nick.Fan@mediatek.com>
Cc: Nicolas Boichat <drinkcat@chromium.org>
Cc: Chen-Yu Tsai <wenst@chromium.org>
Cc: Stephen Boyd <sboyd@kernel.org>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Tested-by: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Link: https://lore.kernel.org/r/20220215184651.12168-1-alyssa.rosenzweig@collabora.com
Signed-off-by: Matthias Brugger <matthias.bgg@gmail.com>
2022-03-01 08:21:28 +01:00

94 lines
2.8 KiB
C

// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
*/
#include <linux/export.h>
#include <linux/jiffies.h>
#include <linux/regmap.h>
#include <linux/mfd/syscon.h>
#include <linux/soc/mediatek/infracfg.h>
#include <asm/processor.h>
#define MTK_POLL_DELAY_US 10
#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
/**
* mtk_infracfg_set_bus_protection - enable bus protection
* @infracfg: The infracfg regmap
* @mask: The mask containing the protection bits to be enabled.
* @reg_update: The boolean flag determines to set the protection bits
* by regmap_update_bits with enable register(PROTECTEN) or
* by regmap_write with set register(PROTECTEN_SET).
*
* This function enables the bus protection bits for disabled power
* domains so that the system does not hang when some unit accesses the
* bus while in power down.
*/
int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
bool reg_update)
{
u32 val;
int ret;
if (reg_update)
regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
mask);
else
regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
val, (val & mask) == mask,
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
return ret;
}
/**
* mtk_infracfg_clear_bus_protection - disable bus protection
* @infracfg: The infracfg regmap
* @mask: The mask containing the protection bits to be disabled.
* @reg_update: The boolean flag determines to clear the protection bits
* by regmap_update_bits with enable register(PROTECTEN) or
* by regmap_write with clear register(PROTECTEN_CLR).
*
* This function disables the bus protection bits previously enabled with
* mtk_infracfg_set_bus_protection.
*/
int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
bool reg_update)
{
int ret;
u32 val;
if (reg_update)
regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
else
regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
val, !(val & mask),
MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
return ret;
}
static int __init mtk_infracfg_init(void)
{
struct regmap *infracfg;
/*
* MT8192 has an experimental path to route GPU traffic to the DSU's
* Accelerator Coherency Port, which is inadvertently enabled by
* default. It turns out not to work, so disable it to prevent spurious
* GPU faults.
*/
infracfg = syscon_regmap_lookup_by_compatible("mediatek,mt8192-infracfg");
if (!IS_ERR(infracfg))
regmap_set_bits(infracfg, MT8192_INFRA_CTRL,
MT8192_INFRA_CTRL_DISABLE_MFG2ACP);
return 0;
}
postcore_initcall(mtk_infracfg_init);