1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2022-2024 Qualcomm Innovation Center, Inc. All rights reserved. 4 * Copyright (c) 2025 Linaro Ltd 5 */ 6 7 #include <linux/iopoll.h> 8 #include <linux/reset.h> 9 10 #include "iris_instance.h" 11 #include "iris_vpu_common.h" 12 #include "iris_vpu_register_defines.h" 13 14 #define WRAPPER_TZ_BASE_OFFS 0x000C0000 15 #define AON_BASE_OFFS 0x000E0000 16 #define AON_MVP_NOC_RESET 0x0001F000 17 18 #define WRAPPER_DEBUG_BRIDGE_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x54) 19 #define WRAPPER_DEBUG_BRIDGE_LPI_STATUS (WRAPPER_BASE_OFFS + 0x58) 20 #define WRAPPER_IRIS_CPU_NOC_LPI_CONTROL (WRAPPER_BASE_OFFS + 0x5C) 21 #define REQ_POWER_DOWN_PREP BIT(0) 22 #define WRAPPER_IRIS_CPU_NOC_LPI_STATUS (WRAPPER_BASE_OFFS + 0x60) 23 #define NOC_LPI_STATUS_DONE BIT(0) /* Indicates the NOC handshake is complete */ 24 #define NOC_LPI_STATUS_DENY BIT(1) /* Indicates the NOC handshake is denied */ 25 #define NOC_LPI_STATUS_ACTIVE BIT(2) /* Indicates the NOC is active */ 26 #define WRAPPER_CORE_CLOCK_CONFIG (WRAPPER_BASE_OFFS + 0x88) 27 #define CORE_CLK_RUN 0x0 28 /* VPU v3.5 */ 29 #define WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0 (WRAPPER_BASE_OFFS + 0x78) 30 31 #define WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG (WRAPPER_TZ_BASE_OFFS + 0x14) 32 #define CTL_AXI_CLK_HALT BIT(0) 33 #define CTL_CLK_HALT BIT(1) 34 35 #define WRAPPER_TZ_QNS4PDXFIFO_RESET (WRAPPER_TZ_BASE_OFFS + 0x18) 36 #define RESET_HIGH BIT(0) 37 38 #define CPU_CS_AHB_BRIDGE_SYNC_RESET (CPU_CS_BASE_OFFS + 0x160) 39 #define CORE_BRIDGE_SW_RESET BIT(0) 40 #define CORE_BRIDGE_HW_RESET_DISABLE BIT(1) 41 42 #define CPU_CS_X2RPMH (CPU_CS_BASE_OFFS + 0x168) 43 #define MSK_SIGNAL_FROM_TENSILICA BIT(0) 44 #define MSK_CORE_POWER_ON BIT(1) 45 46 #define AON_WRAPPER_MVP_NOC_RESET_REQ (AON_MVP_NOC_RESET + 0x000) 47 #define VIDEO_NOC_RESET_REQ (BIT(0) | BIT(1)) 48 49 #define AON_WRAPPER_MVP_NOC_RESET_ACK (AON_MVP_NOC_RESET + 0x004) 50 51 #define VCODEC_SS_IDLE_STATUSN (VCODEC_BASE_OFFS + 0x70) 52 53 #define AON_WRAPPER_MVP_NOC_LPI_CONTROL (AON_BASE_OFFS) 54 #define AON_WRAPPER_MVP_NOC_LPI_STATUS (AON_BASE_OFFS + 0x4) 55 56 #define AON_WRAPPER_MVP_NOC_CORE_SW_RESET (AON_BASE_OFFS + 0x18) 57 #define SW_RESET BIT(0) 58 #define AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL (AON_BASE_OFFS + 0x20) 59 #define NOC_HALT BIT(0) 60 #define AON_WRAPPER_SPARE (AON_BASE_OFFS + 0x28) 61 #define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL (AON_BASE_OFFS + 0x2C) 62 #define AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS (AON_BASE_OFFS + 0x30) 63 64 static bool iris_vpu3x_hw_power_collapsed(struct iris_core *core) 65 { 66 u32 value, pwr_status; 67 68 value = readl(core->reg_base + WRAPPER_CORE_POWER_STATUS); 69 pwr_status = value & BIT(1); 70 71 return pwr_status ? false : true; 72 } 73 74 static void iris_vpu3_power_off_hardware(struct iris_core *core) 75 { 76 u32 reg_val = 0, value, i; 77 int ret; 78 79 if (iris_vpu3x_hw_power_collapsed(core)) 80 goto disable_power; 81 82 dev_err(core->dev, "video hw is power on\n"); 83 84 value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); 85 if (value) 86 writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); 87 88 for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) { 89 ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i, 90 reg_val, reg_val & 0x400000, 2000, 20000); 91 if (ret) 92 goto disable_power; 93 } 94 95 writel(VIDEO_NOC_RESET_REQ, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); 96 97 ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, 98 reg_val, reg_val & 0x3, 200, 2000); 99 if (ret) 100 goto disable_power; 101 102 writel(0x0, core->reg_base + AON_WRAPPER_MVP_NOC_RESET_REQ); 103 104 ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_RESET_ACK, 105 reg_val, !(reg_val & 0x3), 200, 2000); 106 if (ret) 107 goto disable_power; 108 109 writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, 110 core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 111 writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 112 writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 113 114 disable_power: 115 iris_vpu_power_off_hw(core); 116 } 117 118 static void iris_vpu33_power_off_hardware(struct iris_core *core) 119 { 120 bool handshake_done = false, handshake_busy = false; 121 u32 reg_val = 0, value, i; 122 u32 count = 0; 123 int ret; 124 125 if (iris_vpu3x_hw_power_collapsed(core)) 126 goto disable_power; 127 128 dev_err(core->dev, "video hw is power on\n"); 129 130 value = readl(core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); 131 if (value) 132 writel(CORE_CLK_RUN, core->reg_base + WRAPPER_CORE_CLOCK_CONFIG); 133 134 for (i = 0; i < core->iris_platform_data->num_vpp_pipe; i++) { 135 ret = readl_poll_timeout(core->reg_base + VCODEC_SS_IDLE_STATUSN + 4 * i, 136 reg_val, reg_val & 0x400000, 2000, 20000); 137 if (ret) 138 goto disable_power; 139 } 140 141 /* Retry up to 1000 times as recommended by hardware documentation */ 142 do { 143 /* set MNoC to low power */ 144 writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); 145 146 udelay(15); 147 148 value = readl(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS); 149 150 handshake_done = value & NOC_LPI_STATUS_DONE; 151 handshake_busy = value & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); 152 153 if (handshake_done || !handshake_busy) 154 break; 155 156 writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); 157 158 udelay(15); 159 160 } while (++count < 1000); 161 162 if (!handshake_done && handshake_busy) 163 dev_err(core->dev, "LPI handshake timeout\n"); 164 165 ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_NOC_LPI_STATUS, 166 reg_val, reg_val & BIT(0), 200, 2000); 167 if (ret) 168 goto disable_power; 169 170 writel(0, core->reg_base + AON_WRAPPER_MVP_NOC_LPI_CONTROL); 171 172 writel(CORE_BRIDGE_SW_RESET | CORE_BRIDGE_HW_RESET_DISABLE, 173 core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 174 writel(CORE_BRIDGE_HW_RESET_DISABLE, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 175 writel(0x0, core->reg_base + CPU_CS_AHB_BRIDGE_SYNC_RESET); 176 177 disable_power: 178 iris_vpu_power_off_hw(core); 179 } 180 181 static int iris_vpu33_power_off_controller(struct iris_core *core) 182 { 183 u32 xo_rst_tbl_size = core->iris_platform_data->controller_rst_tbl_size; 184 u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; 185 u32 val = 0; 186 int ret; 187 188 writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); 189 190 writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); 191 192 ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS, 193 val, val & BIT(0), 200, 2000); 194 if (ret) 195 goto disable_power; 196 197 writel(0x0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL); 198 199 ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS, 200 val, val == 0, 200, 2000); 201 if (ret) 202 goto disable_power; 203 204 writel(CTL_AXI_CLK_HALT | CTL_CLK_HALT, 205 core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG); 206 writel(RESET_HIGH, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET); 207 writel(0x0, core->reg_base + WRAPPER_TZ_QNS4PDXFIFO_RESET); 208 writel(0x0, core->reg_base + WRAPPER_TZ_CTL_AXI_CLOCK_CONFIG); 209 210 reset_control_bulk_reset(clk_rst_tbl_size, core->resets); 211 212 /* Disable MVP NoC clock */ 213 val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL); 214 val |= NOC_HALT; 215 writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL); 216 217 /* enable MVP NoC reset */ 218 val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET); 219 val |= SW_RESET; 220 writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET); 221 222 /* poll AON spare register bit0 to become zero with 50ms timeout */ 223 ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_SPARE, 224 val, (val & BIT(0)) == 0, 1000, 50000); 225 if (ret) 226 goto disable_power; 227 228 /* enable bit(1) to avoid cvp noc xo reset */ 229 val = readl(core->reg_base + AON_WRAPPER_SPARE); 230 val |= BIT(1); 231 writel(val, core->reg_base + AON_WRAPPER_SPARE); 232 233 reset_control_bulk_assert(xo_rst_tbl_size, core->controller_resets); 234 235 /* De-assert MVP NoC reset */ 236 val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET); 237 val &= ~SW_RESET; 238 writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_SW_RESET); 239 240 usleep_range(80, 100); 241 242 reset_control_bulk_deassert(xo_rst_tbl_size, core->controller_resets); 243 244 /* reset AON spare register */ 245 writel(0, core->reg_base + AON_WRAPPER_SPARE); 246 247 /* Enable MVP NoC clock */ 248 val = readl(core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL); 249 val &= ~NOC_HALT; 250 writel(val, core->reg_base + AON_WRAPPER_MVP_NOC_CORE_CLK_CONTROL); 251 252 iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); 253 254 disable_power: 255 iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); 256 iris_disable_unprepare_clock(core, IRIS_AXI_CLK); 257 258 return 0; 259 } 260 261 static int iris_vpu35_power_on_hw(struct iris_core *core) 262 { 263 int ret; 264 265 ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); 266 if (ret) 267 return ret; 268 269 ret = iris_prepare_enable_clock(core, IRIS_AXI_CLK); 270 if (ret) 271 goto err_disable_power; 272 273 ret = iris_prepare_enable_clock(core, IRIS_HW_FREERUN_CLK); 274 if (ret) 275 goto err_disable_axi_clk; 276 277 ret = iris_prepare_enable_clock(core, IRIS_HW_CLK); 278 if (ret) 279 goto err_disable_hw_free_clk; 280 281 ret = dev_pm_genpd_set_hwmode(core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN], true); 282 if (ret) 283 goto err_disable_hw_clk; 284 285 return 0; 286 287 err_disable_hw_clk: 288 iris_disable_unprepare_clock(core, IRIS_HW_CLK); 289 err_disable_hw_free_clk: 290 iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); 291 err_disable_axi_clk: 292 iris_disable_unprepare_clock(core, IRIS_AXI_CLK); 293 err_disable_power: 294 iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_HW_POWER_DOMAIN]); 295 296 return ret; 297 } 298 299 static void iris_vpu35_power_off_hw(struct iris_core *core) 300 { 301 iris_vpu33_power_off_hardware(core); 302 303 iris_disable_unprepare_clock(core, IRIS_HW_FREERUN_CLK); 304 iris_disable_unprepare_clock(core, IRIS_AXI_CLK); 305 } 306 307 static int iris_vpu35_power_off_controller(struct iris_core *core) 308 { 309 u32 clk_rst_tbl_size = core->iris_platform_data->clk_rst_tbl_size; 310 unsigned int count = 0; 311 u32 val = 0; 312 bool handshake_done, handshake_busy; 313 int ret; 314 315 writel(MSK_SIGNAL_FROM_TENSILICA | MSK_CORE_POWER_ON, core->reg_base + CPU_CS_X2RPMH); 316 317 writel(REQ_POWER_DOWN_PREP, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); 318 319 ret = readl_poll_timeout(core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_STATUS, 320 val, val & BIT(0), 200, 2000); 321 if (ret) 322 goto disable_power; 323 324 writel(0, core->reg_base + WRAPPER_IRIS_CPU_NOC_LPI_CONTROL); 325 326 /* Retry up to 1000 times as recommended by hardware documentation */ 327 do { 328 /* set MNoC to low power */ 329 writel(REQ_POWER_DOWN_PREP, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); 330 331 udelay(15); 332 333 val = readl(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS); 334 335 handshake_done = val & NOC_LPI_STATUS_DONE; 336 handshake_busy = val & (NOC_LPI_STATUS_DENY | NOC_LPI_STATUS_ACTIVE); 337 338 if (handshake_done || !handshake_busy) 339 break; 340 341 writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); 342 343 udelay(15); 344 345 } while (++count < 1000); 346 347 if (!handshake_done && handshake_busy) 348 dev_err(core->dev, "LPI handshake timeout\n"); 349 350 ret = readl_poll_timeout(core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_STATUS, 351 val, val & BIT(0), 200, 2000); 352 if (ret) 353 goto disable_power; 354 355 writel(0, core->reg_base + AON_WRAPPER_MVP_VIDEO_CTL_NOC_LPI_CONTROL); 356 357 writel(0, core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_CONTROL); 358 359 ret = readl_poll_timeout(core->reg_base + WRAPPER_DEBUG_BRIDGE_LPI_STATUS, 360 val, val == 0, 200, 2000); 361 if (ret) 362 goto disable_power; 363 364 disable_power: 365 iris_disable_unprepare_clock(core, IRIS_CTRL_CLK); 366 iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); 367 iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); 368 369 iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); 370 371 reset_control_bulk_reset(clk_rst_tbl_size, core->resets); 372 373 return 0; 374 } 375 376 static int iris_vpu35_power_on_controller(struct iris_core *core) 377 { 378 int ret; 379 380 ret = iris_enable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); 381 if (ret) 382 return ret; 383 384 ret = iris_prepare_enable_clock(core, IRIS_AXI1_CLK); 385 if (ret) 386 goto err_disable_power; 387 388 ret = iris_prepare_enable_clock(core, IRIS_CTRL_FREERUN_CLK); 389 if (ret) 390 goto err_disable_axi1_clk; 391 392 ret = iris_prepare_enable_clock(core, IRIS_CTRL_CLK); 393 if (ret) 394 goto err_disable_ctrl_free_clk; 395 396 return 0; 397 398 err_disable_ctrl_free_clk: 399 iris_disable_unprepare_clock(core, IRIS_CTRL_FREERUN_CLK); 400 err_disable_axi1_clk: 401 iris_disable_unprepare_clock(core, IRIS_AXI1_CLK); 402 err_disable_power: 403 iris_disable_power_domains(core, core->pmdomain_tbl->pd_devs[IRIS_CTRL_POWER_DOMAIN]); 404 405 return ret; 406 } 407 408 static void iris_vpu35_program_bootup_registers(struct iris_core *core) 409 { 410 writel(0x1, core->reg_base + WRAPPER_IRIS_VCODEC_VPU_WRAPPER_SPARE_0); 411 } 412 413 static u64 iris_vpu3x_calculate_frequency(struct iris_inst *inst, size_t data_size) 414 { 415 struct platform_inst_caps *caps = inst->core->iris_platform_data->inst_caps; 416 struct v4l2_format *inp_f = inst->fmt_src; 417 u32 height, width, mbs_per_second, mbpf; 418 u64 fw_cycles, fw_vpp_cycles; 419 u64 vsp_cycles, vpp_cycles; 420 u32 fps = DEFAULT_FPS; 421 422 width = max(inp_f->fmt.pix_mp.width, inst->crop.width); 423 height = max(inp_f->fmt.pix_mp.height, inst->crop.height); 424 425 mbpf = NUM_MBS_PER_FRAME(height, width); 426 mbs_per_second = mbpf * fps; 427 428 fw_cycles = fps * caps->mb_cycles_fw; 429 fw_vpp_cycles = fps * caps->mb_cycles_fw_vpp; 430 431 vpp_cycles = mult_frac(mbs_per_second, caps->mb_cycles_vpp, (u32)inst->fw_caps[PIPE].value); 432 /* 21 / 20 is minimum overhead factor */ 433 vpp_cycles += max(div_u64(vpp_cycles, 20), fw_vpp_cycles); 434 435 /* 1.059 is multi-pipe overhead */ 436 if (inst->fw_caps[PIPE].value > 1) 437 vpp_cycles += div_u64(vpp_cycles * 59, 1000); 438 439 vsp_cycles = fps * data_size * 8; 440 vsp_cycles = div_u64(vsp_cycles, 2); 441 /* VSP FW overhead 1.05 */ 442 vsp_cycles = div_u64(vsp_cycles * 21, 20); 443 444 if (inst->fw_caps[STAGE].value == STAGE_1) 445 vsp_cycles = vsp_cycles * 3; 446 447 return max3(vpp_cycles, vsp_cycles, fw_cycles); 448 } 449 450 const struct vpu_ops iris_vpu3_ops = { 451 .power_off_hw = iris_vpu3_power_off_hardware, 452 .power_on_hw = iris_vpu_power_on_hw, 453 .power_off_controller = iris_vpu_power_off_controller, 454 .power_on_controller = iris_vpu_power_on_controller, 455 .calc_freq = iris_vpu3x_calculate_frequency, 456 }; 457 458 const struct vpu_ops iris_vpu33_ops = { 459 .power_off_hw = iris_vpu33_power_off_hardware, 460 .power_on_hw = iris_vpu_power_on_hw, 461 .power_off_controller = iris_vpu33_power_off_controller, 462 .power_on_controller = iris_vpu_power_on_controller, 463 .calc_freq = iris_vpu3x_calculate_frequency, 464 }; 465 466 const struct vpu_ops iris_vpu35_ops = { 467 .power_off_hw = iris_vpu35_power_off_hw, 468 .power_on_hw = iris_vpu35_power_on_hw, 469 .power_off_controller = iris_vpu35_power_off_controller, 470 .power_on_controller = iris_vpu35_power_on_controller, 471 .program_bootup_registers = iris_vpu35_program_bootup_registers, 472 .calc_freq = iris_vpu3x_calculate_frequency, 473 }; 474