mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
media: ipu6: Add ipu7 buttress support
The ipu7 differs from ipu6 e.g. in power management, authentication, interrupt handling and clock setup. Add support for ipu7 buttress. Signed-off-by: Antti Laakso <antti.laakso@linux.intel.com> Signed-off-by: Sakari Ailus <sakari.ailus@linux.intel.com>
This commit is contained in:
parent
b741032df1
commit
381f97a28c
|
|
@ -345,6 +345,13 @@ irqreturn_t ipu6_buttress_isr(int irq, void *isp_ptr)
|
|||
if (!active)
|
||||
return IRQ_NONE;
|
||||
|
||||
if (IS_IPU7(isp)) {
|
||||
u32 pb_irq;
|
||||
|
||||
pb_irq = readl(isp->pb_base + IPU7_PB_INTERRUPT_STATUS);
|
||||
writel(pb_irq, isp->pb_base + IPU7_PB_INTERRUPT_STATUS);
|
||||
}
|
||||
|
||||
irq_status = readl(isp->base + regs->irq_status);
|
||||
if (irq_status == 0 || WARN_ON_ONCE(irq_status == 0xffffffffu)) {
|
||||
if (active > 0)
|
||||
|
|
@ -442,28 +449,141 @@ irqreturn_t ipu6_buttress_isr_threaded(int irq, void *isp_ptr)
|
|||
return ret;
|
||||
}
|
||||
|
||||
int ipu6_buttress_power(struct device *dev,
|
||||
static int ipu7_isys_d2d_power(struct ipu6_device *isp, bool on)
|
||||
{
|
||||
u32 target = on ? IPU7_BUTTRESS_D2D_PWR_ACK : 0U;
|
||||
u32 val;
|
||||
int ret;
|
||||
|
||||
val = readl(isp->base + IPU7_BUTTRESS_REG_D2D_CTL);
|
||||
if ((val & IPU7_BUTTRESS_D2D_PWR_ACK) == target)
|
||||
return 0;
|
||||
|
||||
if (on)
|
||||
val |= IPU7_BUTTRESS_D2D_PWR_EN;
|
||||
else
|
||||
val &= ~IPU7_BUTTRESS_D2D_PWR_EN;
|
||||
writel(val, isp->base + IPU7_BUTTRESS_REG_D2D_CTL);
|
||||
|
||||
ret = readl_poll_timeout(isp->base + IPU7_BUTTRESS_REG_D2D_CTL, val,
|
||||
(val & IPU7_BUTTRESS_D2D_PWR_ACK) == target,
|
||||
100, BUTTRESS_POWER_TIMEOUT_US);
|
||||
if (ret)
|
||||
dev_err(&isp->pdev->dev, "D2D power %s timeout: 0x%x\n",
|
||||
on ? "up" : "down", val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void ipu7_nde_control(struct ipu6_device *isp, bool on)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = FIELD_PREP(IPU7_NDE_VAL_MASK,
|
||||
on ? IPU7_NDE_VAL_ACTIVE : IPU7_NDE_VAL_DEFAULT) |
|
||||
FIELD_PREP(IPU7_NDE_SCALE_MASK,
|
||||
on ? IPU7_NDE_SCALE_ACTIVE : IPU7_NDE_SCALE_DEFAULT) |
|
||||
FIELD_PREP(IPU7_NDE_VALID_MASK,
|
||||
on ? IPU7_NDE_VALID_ACTIVE : IPU7_NDE_VALID_DEFAULT) |
|
||||
FIELD_PREP(IPU7_NDE_RESVEC_MASK, IPU7_NDE_RESVEC);
|
||||
writel(val, isp->base + IPU7_BUTTRESS_REG_NDE_CONTROL);
|
||||
}
|
||||
|
||||
static int __ipu7_power_on(struct device *dev,
|
||||
const struct ipu6_buttress_ctrl *ctrl)
|
||||
{
|
||||
struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp;
|
||||
bool is_isys = ctrl->subsys_id == IPU_ISYS;
|
||||
u32 pwr_sts, val, ovrd_clk, slp, own_clk_ack;
|
||||
int ret;
|
||||
|
||||
val = ctrl->ratio | (IPU7_FREQ_CTL_CDYN << IPU7_FREQ_CTL_CDYN_SHIFT);
|
||||
pwr_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
|
||||
|
||||
if (is_isys) {
|
||||
ret = ipu7_isys_d2d_power(isp, true);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ipu7_nde_control(isp, true);
|
||||
}
|
||||
|
||||
/* Request clock ownership. */
|
||||
ovrd_clk = is_isys ? IPU7_BUTTRESS_OVERRIDE_IS_CLK :
|
||||
IPU7_BUTTRESS_OVERRIDE_PS_CLK;
|
||||
|
||||
slp = readl(isp->base + IPU7_BUTTRESS_REG_SLEEP_LEVEL_CFG);
|
||||
writel(slp | ovrd_clk, isp->base + IPU7_BUTTRESS_REG_SLEEP_LEVEL_CFG);
|
||||
|
||||
own_clk_ack = is_isys ? IPU7_BUTTRESS_OWN_ACK_IS_CLK :
|
||||
IPU7_BUTTRESS_OWN_ACK_PS_CLK;
|
||||
ret = readl_poll_timeout(isp->base + IPU7_BUTTRESS_REG_SLEEP_LEVEL_STS,
|
||||
slp, (slp & own_clk_ack),
|
||||
100, BUTTRESS_POWER_TIMEOUT_US);
|
||||
if (ret)
|
||||
dev_warn(&isp->pdev->dev, "clock ownership timeout: 0x%x\n",
|
||||
slp);
|
||||
|
||||
writel(val, isp->base + ctrl->freq_ctl);
|
||||
|
||||
ret = readl_poll_timeout(isp->base + isp->buttress.regs->pwr_status,
|
||||
val, (val & ctrl->pwr_sts_mask) == pwr_sts,
|
||||
100, BUTTRESS_POWER_TIMEOUT_US);
|
||||
if (ret) {
|
||||
dev_err(&isp->pdev->dev,
|
||||
"Change power status timeout with 0x%x\n", val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
slp = readl(isp->base + IPU7_BUTTRESS_REG_SLEEP_LEVEL_CFG);
|
||||
writel(slp & ~ovrd_clk, isp->base + IPU7_BUTTRESS_REG_SLEEP_LEVEL_CFG);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __ipu7_power_off(struct device *dev,
|
||||
const struct ipu6_buttress_ctrl *ctrl)
|
||||
{
|
||||
struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp;
|
||||
u32 pwr_sts, val;
|
||||
int ret;
|
||||
|
||||
writel(0x8U, isp->base + ctrl->freq_ctl);
|
||||
|
||||
pwr_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
|
||||
ret = readl_poll_timeout(isp->base + isp->buttress.regs->pwr_status,
|
||||
val, (val & ctrl->pwr_sts_mask) == pwr_sts,
|
||||
100, BUTTRESS_POWER_TIMEOUT_US);
|
||||
if (ret) {
|
||||
dev_err(&isp->pdev->dev,
|
||||
"Change power status timeout with 0x%x\n", val);
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctrl->subsys_id == IPU_ISYS) {
|
||||
ipu7_isys_d2d_power(isp, false);
|
||||
ipu7_nde_control(isp, false);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int __ipu6_power(struct device *dev,
|
||||
const struct ipu6_buttress_ctrl *ctrl, bool on)
|
||||
{
|
||||
struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp;
|
||||
u32 pwr_sts, val;
|
||||
int ret;
|
||||
|
||||
if (!ctrl)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&isp->buttress.power_mutex);
|
||||
|
||||
if (!on) {
|
||||
val = 0;
|
||||
pwr_sts = ctrl->pwr_sts_off << ctrl->pwr_sts_shift;
|
||||
} else {
|
||||
val = BUTTRESS_FREQ_CTL_START |
|
||||
FIELD_PREP(BUTTRESS_FREQ_CTL_RATIO_MASK,
|
||||
ctrl->ratio) |
|
||||
FIELD_PREP(BUTTRESS_FREQ_CTL_QOS_FLOOR_MASK,
|
||||
ctrl->qos_floor) |
|
||||
BUTTRESS_FREQ_CTL_ICCMAX_LEVEL;
|
||||
FIELD_PREP(BUTTRESS_FREQ_CTL_RATIO_MASK, ctrl->ratio) |
|
||||
FIELD_PREP(BUTTRESS_FREQ_CTL_QOS_FLOOR_MASK,
|
||||
ctrl->qos_floor) |
|
||||
BUTTRESS_FREQ_CTL_ICCMAX_LEVEL;
|
||||
|
||||
pwr_sts = ctrl->pwr_sts_on << ctrl->pwr_sts_shift;
|
||||
}
|
||||
|
|
@ -477,6 +597,26 @@ int ipu6_buttress_power(struct device *dev,
|
|||
dev_err(&isp->pdev->dev,
|
||||
"Change power status timeout with 0x%x\n", val);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ipu6_buttress_power(struct device *dev,
|
||||
const struct ipu6_buttress_ctrl *ctrl, bool on)
|
||||
{
|
||||
struct ipu6_device *isp = to_ipu6_bus_device(dev)->isp;
|
||||
int ret;
|
||||
|
||||
if (!ctrl)
|
||||
return 0;
|
||||
|
||||
mutex_lock(&isp->buttress.power_mutex);
|
||||
|
||||
if (IS_IPU7(isp))
|
||||
ret = on ? __ipu7_power_on(dev, ctrl) :
|
||||
__ipu7_power_off(dev, ctrl);
|
||||
else
|
||||
ret = __ipu6_power(dev, ctrl, on);
|
||||
|
||||
mutex_unlock(&isp->buttress.power_mutex);
|
||||
|
||||
return ret;
|
||||
|
|
@ -634,11 +774,18 @@ int ipu6_buttress_authenticate(struct ipu6_device *isp)
|
|||
* Write address of FIT table to FW_SOURCE register
|
||||
* Let's use fw address. I.e. not using FIT table yet
|
||||
*/
|
||||
data = lower_32_bits(isp->psys->pkg_dir_dma_addr);
|
||||
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_LO);
|
||||
if (IS_IPU7(isp)) {
|
||||
writel(isp->cpd_fw->size,
|
||||
isp->base + IPU7_BUTTRESS_REG_FW_SOURCE_SIZE);
|
||||
writel(sg_dma_address(isp->psys->fw_sgt.sgl),
|
||||
isp->base + IPU7_BUTTRESS_REG_FW_SOURCE_BASE);
|
||||
} else {
|
||||
data = lower_32_bits(isp->psys->pkg_dir_dma_addr);
|
||||
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_LO);
|
||||
|
||||
data = upper_32_bits(isp->psys->pkg_dir_dma_addr);
|
||||
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_HI);
|
||||
data = upper_32_bits(isp->psys->pkg_dir_dma_addr);
|
||||
writel(data, isp->base + BUTTRESS_REG_FW_SOURCE_BASE_HI);
|
||||
}
|
||||
|
||||
/*
|
||||
* Write boot_load into IU2CSEDATA0
|
||||
|
|
@ -674,8 +821,11 @@ int ipu6_buttress_authenticate(struct ipu6_device *isp)
|
|||
goto out_unlock;
|
||||
}
|
||||
|
||||
ret = readl_poll_timeout(psys_pdata->base + BOOTLOADER_STATUS_OFFSET,
|
||||
data, data == BOOTLOADER_MAGIC_KEY, 500,
|
||||
void __iomem *base = IS_IPU7(isp) ?
|
||||
isp->base + IPU7_BUTTRESS_REG_FW_BOOT_PARAMS7 :
|
||||
psys_pdata->base + BOOTLOADER_STATUS_OFFSET;
|
||||
|
||||
ret = readl_poll_timeout(base, data, data == BOOTLOADER_MAGIC_KEY, 500,
|
||||
BUTTRESS_CSE_BOOTLOAD_TIMEOUT_US);
|
||||
if (ret) {
|
||||
dev_err(&isp->pdev->dev, "Unexpected magic number 0x%x\n",
|
||||
|
|
@ -815,12 +965,61 @@ u64 ipu6_buttress_tsc_ticks_to_ns(u64 ticks, const struct ipu6_device *isp)
|
|||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ipu6_buttress_tsc_ticks_to_ns, "INTEL_IPU6");
|
||||
|
||||
/* trigger uc control to wakeup fw */
|
||||
void ipu7_buttress_wakeup_isys(const struct ipu6_device *isp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(isp->base + IPU7_BUTTRESS_REG_ISYS_UCX_CTRL_STATUS);
|
||||
val |= IPU7_UCX_CTL_WAKEUP;
|
||||
writel(val, isp->base + IPU7_BUTTRESS_REG_ISYS_UCX_CTRL_STATUS);
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ipu7_buttress_wakeup_isys, "INTEL_IPU6");
|
||||
|
||||
u32 ipu7_buttress_get_isys_freq(struct ipu6_device *isp)
|
||||
{
|
||||
u32 val;
|
||||
|
||||
val = readl(isp->base + IPU7_BUTTRESS_REG_IS_WORKPOINT_REQ);
|
||||
val &= IPU7_BUTTRESS_IS_FREQ_CTL_RATIO_MASK;
|
||||
|
||||
return val * 50 / 3;
|
||||
}
|
||||
EXPORT_SYMBOL_NS_GPL(ipu7_buttress_get_isys_freq, "INTEL_IPU6");
|
||||
|
||||
static void ipu7_buttress_setup(struct ipu6_device *isp)
|
||||
{
|
||||
struct ipu6_buttress *b = &isp->buttress;
|
||||
u32 val;
|
||||
|
||||
/* program PB BAR */
|
||||
writel(0, isp->pb_base + IPU7_GLOBAL_INTERRUPT_MASK);
|
||||
val = readl(isp->pb_base + IPU7_BAR2_MISC_CONFIG);
|
||||
val |= 0x100U;
|
||||
|
||||
writel(val, isp->pb_base + IPU7_BAR2_MISC_CONFIG);
|
||||
|
||||
writel(BIT(22), isp->pb_base + IPU7_TLBID_HASH_ENABLE_63_32);
|
||||
writel(BIT(1), isp->pb_base + IPU7_TLBID_HASH_ENABLE_127_96);
|
||||
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_clear);
|
||||
writel(b->regs->irq_all, isp->base + IPU7_BUTTRESS_REG_IRQ_MASK);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_enable);
|
||||
|
||||
/* LNL SW workaround for PS PD hang when PS sub-domain during PD */
|
||||
writel(IPU7_BUTTRESS_CG_CTRL_PS_FSM_CG, isp->base + IPU7_BUTTRESS_REG_CG_CTRL_BITS);
|
||||
}
|
||||
|
||||
void ipu6_buttress_restore(struct ipu6_device *isp)
|
||||
{
|
||||
struct ipu6_buttress *b = &isp->buttress;
|
||||
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_clear);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_enable);
|
||||
if (IS_IPU7(isp)) {
|
||||
ipu7_buttress_setup(isp);
|
||||
} else {
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_clear);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_enable);
|
||||
}
|
||||
writel(b->wdt_cached_value, isp->base + b->regs->wdt);
|
||||
}
|
||||
|
||||
|
|
@ -838,37 +1037,44 @@ int ipu6_buttress_init(struct ipu6_device *isp)
|
|||
init_completion(&b->ipc.recv_complete);
|
||||
|
||||
INIT_LIST_HEAD(&b->constraints);
|
||||
|
||||
isp->secure_mode = ipu6_buttress_get_secure_mode(isp);
|
||||
dev_dbg(&isp->pdev->dev, "IPU6 in %s mode touch 0x%x mask 0x%x\n",
|
||||
isp->secure_mode ? "secure" : "non-secure",
|
||||
readl(isp->base + BUTTRESS_REG_SECURITY_TOUCH),
|
||||
readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
|
||||
|
||||
b->wdt_cached_value = readl(isp->base + b->regs->wdt);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_clear);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_enable);
|
||||
dev_dbg(&isp->pdev->dev, "IPU in %s mode\n",
|
||||
isp->secure_mode ? "secure" : "non-secure");
|
||||
|
||||
/* get ref_clk frequency by reading the indication in btrs control */
|
||||
val = readl(isp->base + b->regs->btrs_ctrl);
|
||||
val = FIELD_GET(BUTTRESS_REG_BTRS_CTRL_REF_CLK_IND, val);
|
||||
|
||||
switch (val) {
|
||||
case 0x0:
|
||||
b->ref_clk = 240;
|
||||
break;
|
||||
case 0x1:
|
||||
b->ref_clk = 192;
|
||||
break;
|
||||
case 0x2:
|
||||
if (IS_IPU7(isp)) {
|
||||
ipu7_buttress_setup(isp);
|
||||
b->ref_clk = 384;
|
||||
break;
|
||||
default:
|
||||
dev_warn(&isp->pdev->dev,
|
||||
"Unsupported ref clock, use 19.2Mhz by default.\n");
|
||||
b->ref_clk = 192;
|
||||
break;
|
||||
} else {
|
||||
dev_dbg(&isp->pdev->dev, "IPU6 touch 0x%x mask 0x%x\n",
|
||||
readl(isp->base + BUTTRESS_REG_SECURITY_TOUCH),
|
||||
readl(isp->base + BUTTRESS_REG_CAMERA_MASK));
|
||||
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_clear);
|
||||
writel(b->regs->irq_all, isp->base + b->regs->irq_enable);
|
||||
|
||||
/* get ref_clk frequency by reading the indication in btrs control */
|
||||
val = readl(isp->base + b->regs->btrs_ctrl);
|
||||
val = FIELD_GET(BUTTRESS_REG_BTRS_CTRL_REF_CLK_IND, val);
|
||||
|
||||
switch (val) {
|
||||
case 0x0:
|
||||
b->ref_clk = 240;
|
||||
break;
|
||||
case 0x1:
|
||||
b->ref_clk = 192;
|
||||
break;
|
||||
case 0x2:
|
||||
b->ref_clk = 384;
|
||||
break;
|
||||
default:
|
||||
dev_warn(&isp->pdev->dev,
|
||||
"Unsupported ref clock, use 19.2Mhz by default.\n");
|
||||
b->ref_clk = 192;
|
||||
break;
|
||||
}
|
||||
}
|
||||
b->wdt_cached_value = readl(isp->base + b->regs->wdt);
|
||||
|
||||
/* Retry couple of times in case of CSE initialization is delayed */
|
||||
do {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ struct ipu6_buttress_ctrl {
|
|||
u32 freq_ctl, pwr_sts_shift, pwr_sts_mask, pwr_sts_on, pwr_sts_off;
|
||||
unsigned int ratio;
|
||||
unsigned int qos_floor;
|
||||
int subsys_id;
|
||||
};
|
||||
|
||||
struct ipu6_buttress_ipc {
|
||||
|
|
@ -104,4 +105,6 @@ void ipu6_buttress_exit(struct ipu6_device *isp);
|
|||
void ipu6_buttress_csi_port_config(struct ipu6_device *isp,
|
||||
u32 legacy, u32 combo);
|
||||
void ipu6_buttress_restore(struct ipu6_device *isp);
|
||||
void ipu7_buttress_wakeup_isys(const struct ipu6_device *isp);
|
||||
u32 ipu7_buttress_get_isys_freq(struct ipu6_device *isp);
|
||||
#endif /* IPU6_BUTTRESS_H */
|
||||
|
|
|
|||
|
|
@ -221,4 +221,106 @@ enum {
|
|||
#define BUTTRESS_EVENT (BUTTRESS_ISR_IPC_FROM_CSE_IS_WAITING | \
|
||||
BUTTRESS_ISR_IPC_EXEC_DONE_BY_CSE | \
|
||||
BUTTRESS_ISR_SAI_VIOLATION)
|
||||
|
||||
/* IPU7 */
|
||||
|
||||
/* IPU7 buttress register offsets */
|
||||
#define IPU7_BUTTRESS_REG_SKU 0x3030
|
||||
#define IPU7_BUTTRESS_REG_IRQ_STATUS 0x2000
|
||||
#define IPU7_BUTTRESS_REG_IRQ_ENABLE 0x2008
|
||||
#define IPU7_BUTTRESS_REG_IRQ_CLEAR 0x200c
|
||||
#define IPU7_BUTTRESS_REG_IRQ_MASK 0x2010
|
||||
#define IPU7_BUTTRESS_REG_TSC_CMD 0x2014
|
||||
#define IPU7_BUTTRESS_REG_TSC_CTL 0x2018
|
||||
#define IPU7_BUTTRESS_REG_TSC_LO 0x201c
|
||||
#define IPU7_BUTTRESS_REG_IS_WORKPOINT_REQ 0x2104
|
||||
#define IPU7_BUTTRESS_REG_PS_WORKPOINT_REQ 0x2100
|
||||
#define IPU7_BUTTRESS_REG_IDLE_WDT 0x218c
|
||||
#define IPU7_BUTTRESS_REG_ISYS_UCX_CTRL_STATUS 0x2200
|
||||
#define IPU7_BUTTRESS_REG_ISYS_UCX_START_ADDR 0x2204
|
||||
#define IPU7_BUTTRESS_REG_PSYS_UCX_CTRL_STATUS 0x2208
|
||||
#define IPU7_BUTTRESS_REG_PSYS_UCX_START_ADDR 0x220c
|
||||
#define IPU7_BUTTRESS_REG_SECURITY_CTL 0x2318
|
||||
#define IPU7_BUTTRESS_REG_FW_RESET_CTL 0x2334
|
||||
#define IPU7_BUTTRESS_REG_FW_SOURCE_SIZE 0x2338
|
||||
#define IPU7_BUTTRESS_REG_FW_SOURCE_BASE 0x233c
|
||||
#define IPU7_BUTTRESS_REG_CSE2IUDB0 0x2500
|
||||
#define IPU7_BUTTRESS_REG_CSE2IUDATA0 0x2504
|
||||
#define IPU7_BUTTRESS_REG_CSE2IUCSR 0x2508
|
||||
#define IPU7_BUTTRESS_REG_IU2CSEDB0 0x250c
|
||||
#define IPU7_BUTTRESS_REG_IU2CSEDATA0 0x2510
|
||||
#define IPU7_BUTTRESS_REG_IU2CSECSR 0x2514
|
||||
#define IPU7_BUTTRESS_REG_CG_CTRL_BITS 0x3014
|
||||
#define IPU7_BUTTRESS_REG_FW_BOOT_PARAMS0 0x4000
|
||||
#define IPU7_BUTTRESS_REG_FW_BOOT_PARAMS7 0x401c
|
||||
#define IPU7_BUTTRESS_REG_PWR_STATUS 0x2114
|
||||
|
||||
#define IPU7_BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE BIT(0)
|
||||
#define IPU7_BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING BIT(1)
|
||||
#define IPU7_BUTTRESS_IRQ_CSE_CSR_SET BIT(2)
|
||||
#define IPU7_BUTTRESS_IRQ_SAI_VIOLATION BIT(4)
|
||||
#define IPU7_BUTTRESS_IRQ_IS_IRQ BIT(30)
|
||||
#define IPU7_BUTTRESS_IRQ_PS_IRQ BIT(31)
|
||||
|
||||
#define IPU7_BUTTRESS_IRQS (IPU7_BUTTRESS_IRQ_IS_IRQ | \
|
||||
IPU7_BUTTRESS_IRQ_PS_IRQ | \
|
||||
IPU7_BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING | \
|
||||
IPU7_BUTTRESS_IRQ_CSE_CSR_SET | \
|
||||
IPU7_BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE)
|
||||
|
||||
/* LNL SW workaround for PS PD hang */
|
||||
#define IPU7_BUTTRESS_CG_CTRL_PS_FSM_CG BIT(3)
|
||||
|
||||
/* P-unit Bridge (PB) BAR registers */
|
||||
#define IPU7_PB_INTERRUPT_STATUS 0x0
|
||||
|
||||
/* Frequency control encoding */
|
||||
#define IPU7_FREQ_CTL_CDYN 0x80
|
||||
#define IPU7_FREQ_CTL_CDYN_SHIFT 8
|
||||
#define IPU7_BUTTRESS_IS_FREQ_CTL_RATIO_MASK GENMASK(7, 0)
|
||||
#define IPU7_IS_FREQ_CTL_DEFAULT_RATIO 0x1b
|
||||
#define IPU7_PS_FREQ_CTL_DEFAULT_RATIO 0x14
|
||||
|
||||
/* D2D power control */
|
||||
#define IPU7_BUTTRESS_REG_D2D_CTL 0x21d4
|
||||
#define IPU7_BUTTRESS_D2D_PWR_EN BIT(0)
|
||||
#define IPU7_BUTTRESS_D2D_PWR_ACK BIT(4)
|
||||
|
||||
#define IPU7_BUTTRESS_PWR_STATE_IS_PWR_SHIFT 0
|
||||
#define IPU7_BUTTRESS_PWR_STATE_IS_PWR_MASK (0x3U << 0)
|
||||
#define IPU7_BUTTRESS_PWR_STATE_PS_PWR_SHIFT 4
|
||||
#define IPU7_BUTTRESS_PWR_STATE_PS_PWR_MASK (0x3U << 4)
|
||||
|
||||
/* NDE */
|
||||
#define IPU7_BUTTRESS_REG_NDE_CONTROL 0x21a4
|
||||
#define IPU7_NDE_VAL_MASK GENMASK(9, 0)
|
||||
#define IPU7_NDE_SCALE_MASK GENMASK(12, 10)
|
||||
#define IPU7_NDE_VALID_MASK BIT(13)
|
||||
#define IPU7_NDE_RESVEC_MASK GENMASK(19, 16)
|
||||
#define IPU7_NDE_VAL_ACTIVE 48
|
||||
#define IPU7_NDE_SCALE_ACTIVE 2
|
||||
#define IPU7_NDE_VALID_ACTIVE 1
|
||||
#define IPU7_NDE_VAL_DEFAULT 1023
|
||||
#define IPU7_NDE_SCALE_DEFAULT 2
|
||||
#define IPU7_NDE_VALID_DEFAULT 0
|
||||
#define IPU7_NDE_RESVEC 0xe
|
||||
|
||||
/* IS UCX control */
|
||||
#define IPU7_UCX_CTL_RESET BIT(0)
|
||||
#define IPU7_UCX_CTL_RUN BIT(1)
|
||||
#define IPU7_UCX_CTL_WAKEUP BIT(2)
|
||||
|
||||
#define IPU7_BUTTRESS_REG_SLEEP_LEVEL_CFG 0x21b0
|
||||
#define IPU7_BUTTRESS_REG_SLEEP_LEVEL_STS 0x21b4
|
||||
#define IPU7_BUTTRESS_OVERRIDE_IS_CLK BIT(1)
|
||||
#define IPU7_BUTTRESS_OWN_ACK_IS_CLK BIT(9)
|
||||
#define IPU7_BUTTRESS_OVERRIDE_PS_CLK BIT(2)
|
||||
#define IPU7_BUTTRESS_OWN_ACK_PS_CLK BIT(10)
|
||||
|
||||
/* PB registers */
|
||||
#define IPU7_GLOBAL_INTERRUPT_MASK 0x8
|
||||
#define IPU7_TLBID_HASH_ENABLE_63_32 0x34
|
||||
#define IPU7_TLBID_HASH_ENABLE_127_96 0x3c
|
||||
#define IPU7_BAR2_MISC_CONFIG 0x64
|
||||
|
||||
#endif /* IPU6_PLATFORM_BUTTRESS_REGS_H */
|
||||
|
|
|
|||
|
|
@ -34,6 +34,7 @@
|
|||
#include "ipu6-platform-regs.h"
|
||||
|
||||
#define IPU6_PCI_BAR 0
|
||||
#define IPU7_PCI_PBBAR 4
|
||||
|
||||
struct ipu6_cell_program {
|
||||
u32 magic_number;
|
||||
|
|
@ -209,6 +210,7 @@ static struct ipu6_psys_internal_pdata psys_ipdata = {
|
|||
};
|
||||
|
||||
static const struct ipu6_buttress_ctrl isys_buttress_ctrl = {
|
||||
.subsys_id = IPU_ISYS,
|
||||
.ratio = IPU6_IS_FREQ_CTL_DEFAULT_RATIO,
|
||||
.qos_floor = IPU6_IS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO,
|
||||
.freq_ctl = IPU6_BUTTRESS_REG_IS_FREQ_CTL,
|
||||
|
|
@ -219,6 +221,7 @@ static const struct ipu6_buttress_ctrl isys_buttress_ctrl = {
|
|||
};
|
||||
|
||||
static const struct ipu6_buttress_ctrl psys_buttress_ctrl = {
|
||||
.subsys_id = IPU_PSYS,
|
||||
.ratio = IPU6_PS_FREQ_CTL_DEFAULT_RATIO,
|
||||
.qos_floor = IPU6_PS_FREQ_CTL_DEFAULT_QOS_FLOOR_RATIO,
|
||||
.freq_ctl = IPU6_BUTTRESS_REG_PS_FREQ_CTL,
|
||||
|
|
@ -228,6 +231,28 @@ static const struct ipu6_buttress_ctrl psys_buttress_ctrl = {
|
|||
.pwr_sts_off = IPU6_BUTTRESS_PWR_STATE_DN_DONE,
|
||||
};
|
||||
|
||||
static const struct ipu6_buttress_ctrl ipu7_isys_buttress_ctrl = {
|
||||
.subsys_id = IPU_ISYS,
|
||||
.ratio = IPU7_IS_FREQ_CTL_DEFAULT_RATIO,
|
||||
.qos_floor = 0,
|
||||
.freq_ctl = IPU7_BUTTRESS_REG_IS_WORKPOINT_REQ,
|
||||
.pwr_sts_shift = IPU7_BUTTRESS_PWR_STATE_IS_PWR_SHIFT,
|
||||
.pwr_sts_mask = IPU7_BUTTRESS_PWR_STATE_IS_PWR_MASK,
|
||||
.pwr_sts_on = IPU6_BUTTRESS_PWR_STATE_UP_DONE,
|
||||
.pwr_sts_off = IPU6_BUTTRESS_PWR_STATE_DN_DONE,
|
||||
};
|
||||
|
||||
static const struct ipu6_buttress_ctrl ipu7_psys_buttress_ctrl = {
|
||||
.subsys_id = IPU_PSYS,
|
||||
.ratio = IPU7_PS_FREQ_CTL_DEFAULT_RATIO,
|
||||
.qos_floor = 0,
|
||||
.freq_ctl = IPU7_BUTTRESS_REG_PS_WORKPOINT_REQ,
|
||||
.pwr_sts_shift = IPU7_BUTTRESS_PWR_STATE_PS_PWR_SHIFT,
|
||||
.pwr_sts_mask = IPU7_BUTTRESS_PWR_STATE_PS_PWR_MASK,
|
||||
.pwr_sts_on = IPU6_BUTTRESS_PWR_STATE_UP_DONE,
|
||||
.pwr_sts_off = IPU6_BUTTRESS_PWR_STATE_DN_DONE,
|
||||
};
|
||||
|
||||
static const struct ipu6_buttress_registers ipu6_buttress_regs = {
|
||||
/* Registers */
|
||||
.irq_status = BUTTRESS_REG_ISR_STATUS,
|
||||
|
|
@ -258,6 +283,35 @@ static const struct ipu6_buttress_registers ipu6_buttress_regs = {
|
|||
.irq_sai = BUTTRESS_ISR_SAI_VIOLATION,
|
||||
};
|
||||
|
||||
static const struct ipu6_buttress_registers ipu7_buttress_regs = {
|
||||
/* Registers */
|
||||
.irq_status = IPU7_BUTTRESS_REG_IRQ_STATUS,
|
||||
.irq_clear = IPU7_BUTTRESS_REG_IRQ_CLEAR,
|
||||
.irq_enable = IPU7_BUTTRESS_REG_IRQ_ENABLE,
|
||||
.pwr_status = IPU7_BUTTRESS_REG_PWR_STATUS,
|
||||
.security_ctl = IPU7_BUTTRESS_REG_SECURITY_CTL,
|
||||
.fw_reset_ctl = IPU7_BUTTRESS_REG_FW_RESET_CTL,
|
||||
.fabric_cmd = IPU7_BUTTRESS_REG_TSC_CMD,
|
||||
.tsw_ctl = IPU7_BUTTRESS_REG_TSC_CTL,
|
||||
.tsc_lo = IPU7_BUTTRESS_REG_TSC_LO,
|
||||
.wdt = IPU7_BUTTRESS_REG_IDLE_WDT,
|
||||
.csr_in = IPU7_BUTTRESS_REG_CSE2IUCSR,
|
||||
.csr_out = IPU7_BUTTRESS_REG_IU2CSECSR,
|
||||
.db0_in = IPU7_BUTTRESS_REG_CSE2IUDB0,
|
||||
.db0_out = IPU7_BUTTRESS_REG_IU2CSEDB0,
|
||||
.data0_in = IPU7_BUTTRESS_REG_CSE2IUDATA0,
|
||||
.data0_out = IPU7_BUTTRESS_REG_IU2CSEDATA0,
|
||||
|
||||
/* Bitmasks */
|
||||
.irq_is = IPU7_BUTTRESS_IRQ_IS_IRQ,
|
||||
.irq_ps = IPU7_BUTTRESS_IRQ_PS_IRQ,
|
||||
.irq_all = IPU7_BUTTRESS_IRQS,
|
||||
.irq_events = IPU7_BUTTRESS_IRQS,
|
||||
.irq_cse_ipc = IPU7_BUTTRESS_IRQ_IPC_FROM_CSE_IS_WAITING,
|
||||
.irq_exec_done = IPU7_BUTTRESS_IRQ_IPC_EXEC_DONE_BY_CSE,
|
||||
.irq_sai = IPU7_BUTTRESS_IRQ_SAI_VIOLATION,
|
||||
};
|
||||
|
||||
static void
|
||||
ipu6_pkg_dir_configure_spc(struct ipu6_device *isp,
|
||||
const struct ipu6_hw_variants *hw_variant,
|
||||
|
|
@ -532,24 +586,6 @@ static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
if (!isp)
|
||||
return -ENOMEM;
|
||||
|
||||
isp->pdev = pdev;
|
||||
INIT_LIST_HEAD(&isp->devices);
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Enable PCI device failed\n");
|
||||
|
||||
phys = pci_resource_start(pdev, IPU6_PCI_BAR);
|
||||
dev_dbg(dev, "IPU6 PCI bar[%u] = %pa\n", IPU6_PCI_BAR, &phys);
|
||||
|
||||
isp->base = pcim_iomap_region(pdev, IPU6_PCI_BAR, IPU6_NAME);
|
||||
if (IS_ERR(isp->base))
|
||||
return dev_err_probe(dev, PTR_ERR(isp->base),
|
||||
"Failed to I/O mem remapping\n");
|
||||
|
||||
pci_set_drvdata(pdev, isp);
|
||||
pci_set_master(pdev);
|
||||
|
||||
isp->cpd_metadata_cmpnt_size = sizeof(struct ipu6_cpd_metadata_cmpnt);
|
||||
isp->buttress.regs = &ipu6_buttress_regs;
|
||||
|
||||
|
|
@ -577,12 +613,44 @@ static int ipu6_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
|
|||
isp->hw_ver = IPU_VERSION_6EP_MTL;
|
||||
isp->cpd_fw_name = IPU6EPMTL_FIRMWARE_NAME;
|
||||
break;
|
||||
case PCI_DEVICE_ID_INTEL_IPU7:
|
||||
isp->hw_ver = IPU_VERSION_7;
|
||||
isp->cpd_fw_name = IPU7_FIRMWARE_NAME;
|
||||
isp->buttress.regs = &ipu7_buttress_regs;
|
||||
break;
|
||||
default:
|
||||
return dev_err_probe(dev, -ENODEV,
|
||||
"Unsupported IPU6 device %x\n",
|
||||
id->device);
|
||||
}
|
||||
|
||||
isp->pdev = pdev;
|
||||
INIT_LIST_HEAD(&isp->devices);
|
||||
|
||||
ret = pcim_enable_device(pdev);
|
||||
if (ret)
|
||||
return dev_err_probe(dev, ret, "Enable PCI device failed\n");
|
||||
|
||||
phys = pci_resource_start(pdev, IPU6_PCI_BAR);
|
||||
dev_dbg(dev, "IPU6 PCI bar[%u] = %pa\n", IPU6_PCI_BAR, &phys);
|
||||
|
||||
isp->base = pcim_iomap_region(pdev, IPU6_PCI_BAR, IPU6_NAME);
|
||||
if (IS_ERR(isp->base))
|
||||
return dev_err_probe(dev, PTR_ERR(isp->base),
|
||||
"Failed to I/O mem remapping\n");
|
||||
|
||||
if (IS_IPU7(isp)) {
|
||||
isp->pb_base = pcim_iomap_region(pdev, IPU7_PCI_PBBAR,
|
||||
IPU6_NAME);
|
||||
if (IS_ERR(isp->pb_base))
|
||||
return dev_err_probe(dev, PTR_ERR(isp->pb_base),
|
||||
"I/O remapping PB BAR %u failed\n",
|
||||
IPU7_PCI_PBBAR);
|
||||
}
|
||||
|
||||
pci_set_drvdata(pdev, isp);
|
||||
pci_set_master(pdev);
|
||||
|
||||
ipu6_internal_pdata_init(isp);
|
||||
|
||||
isys_base = isp->base + isys_ipdata.hw_variant.offset;
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ struct ipu6_bus_device;
|
|||
#define IPU6_FIRMWARE_NAME "intel/ipu/ipu6_fw.bin"
|
||||
#define IPU6EPMTL_FIRMWARE_NAME "intel/ipu/ipu6epmtl_fw.bin"
|
||||
#define IPU6EPADLN_FIRMWARE_NAME "intel/ipu/ipu6epadln_fw.bin"
|
||||
#define IPU7_FIRMWARE_NAME "intel/ipu/ipu7_fw.bin"
|
||||
|
||||
#define IPU_VERSION_6 BIT(0) /* TGL */
|
||||
#define IPU_VERSION_6SE BIT(1) /* JSL */
|
||||
|
|
@ -64,6 +65,7 @@ struct ipu6_device {
|
|||
u32 cpd_metadata_cmpnt_size;
|
||||
|
||||
void __iomem *base;
|
||||
void __iomem *pb_base;
|
||||
bool need_ipc_reset;
|
||||
bool secure_mode;
|
||||
u8 hw_ver;
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@
|
|||
#define PCI_DEVICE_ID_INTEL_IPU6EP_ADLN 0x462e
|
||||
#define PCI_DEVICE_ID_INTEL_IPU6EP_RPLP 0xa75d
|
||||
#define PCI_DEVICE_ID_INTEL_IPU6EP_MTL 0x7d19
|
||||
#define PCI_DEVICE_ID_INTEL_IPU7 0x645d
|
||||
#define PCI_DEVICE_ID_INTEL_IPU7P5 0xb05d
|
||||
|
||||
static const struct pci_device_id ipu6_pci_tbl[] = {
|
||||
{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IPU6) },
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user