11// SPDX-License-Identifier: GPL-2.0-only
22/*
3- * Copyright (C) 2020-2024 Intel Corporation
3+ * Copyright (C) 2020-2025 Intel Corporation
44 */
55
6+ #include <linux/units.h>
7+
68#include "ivpu_drv.h"
79#include "ivpu_hw.h"
810#include "ivpu_hw_btrs.h"
2830
2931#define BTRS_LNL_ALL_IRQ_MASK ((u32)-1)
3032
31- #define BTRS_MTL_WP_CONFIG_1_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_5_3)
32- #define BTRS_MTL_WP_CONFIG_1_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_1_TILE, MTL_PLL_RATIO_4_3)
33- #define BTRS_MTL_WP_CONFIG_2_TILE_5_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_5_3)
34- #define BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO WP_CONFIG(MTL_CONFIG_2_TILE, MTL_PLL_RATIO_4_3)
35- #define BTRS_MTL_WP_CONFIG_0_TILE_PLL_OFF WP_CONFIG(0, 0)
3633
3734#define PLL_CDYN_DEFAULT 0x80
3835#define PLL_EPP_DEFAULT 0x80
3936#define PLL_CONFIG_DEFAULT 0x0
40- #define PLL_SIMULATION_FREQ 10000000
41- #define PLL_REF_CLK_FREQ 50000000
37+ #define PLL_REF_CLK_FREQ 50000000ull
38+ #define PLL_RATIO_TO_FREQ (x ) ((x) * PLL_REF_CLK_FREQ)
39+
4240#define PLL_TIMEOUT_US (1500 * USEC_PER_MSEC)
4341#define IDLE_TIMEOUT_US (5 * USEC_PER_MSEC)
4442#define TIMEOUT_US (150 * USEC_PER_MSEC)
6260#define DCT_ENABLE 0x1
6361#define DCT_DISABLE 0x0
6462
63+ static u32 pll_ratio_to_dpu_freq (struct ivpu_device * vdev , u32 ratio );
64+
6565int ivpu_hw_btrs_irqs_clear_with_0_mtl (struct ivpu_device * vdev )
6666{
6767 REGB_WR32 (VPU_HW_BTRS_MTL_INTERRUPT_STAT , BTRS_MTL_ALL_IRQ_MASK );
@@ -156,7 +156,7 @@ static int info_init_mtl(struct ivpu_device *vdev)
156156
157157 hw -> tile_fuse = BTRS_MTL_TILE_FUSE_ENABLE_BOTH ;
158158 hw -> sku = BTRS_MTL_TILE_SKU_BOTH ;
159- hw -> config = BTRS_MTL_WP_CONFIG_2_TILE_4_3_RATIO ;
159+ hw -> config = WP_CONFIG ( MTL_CONFIG_2_TILE , MTL_PLL_RATIO_4_3 ) ;
160160
161161 return 0 ;
162162}
@@ -334,8 +334,8 @@ int ivpu_hw_btrs_wp_drive(struct ivpu_device *vdev, bool enable)
334334
335335 prepare_wp_request (vdev , & wp , enable );
336336
337- ivpu_dbg (vdev , PM , "PLL workpoint request: %u Hz , config: 0x%x, epp: 0x%x, cdyn: 0x%x\n" ,
338- PLL_RATIO_TO_FREQ ( wp .target ), wp .cfg , wp .epp , wp .cdyn );
337+ ivpu_dbg (vdev , PM , "PLL workpoint request: %lu MHz , config: 0x%x, epp: 0x%x, cdyn: 0x%x\n" ,
338+ pll_ratio_to_dpu_freq ( vdev , wp .target ) / HZ_PER_MHZ , wp .cfg , wp .epp , wp .cdyn );
339339
340340 ret = wp_request_send (vdev , & wp );
341341 if (ret ) {
@@ -573,6 +573,47 @@ int ivpu_hw_btrs_wait_for_idle(struct ivpu_device *vdev)
573573 return REGB_POLL_FLD (VPU_HW_BTRS_LNL_VPU_STATUS , IDLE , 0x1 , IDLE_TIMEOUT_US );
574574}
575575
576+ static u32 pll_config_get_mtl (struct ivpu_device * vdev )
577+ {
578+ return REGB_RD32 (VPU_HW_BTRS_MTL_CURRENT_PLL );
579+ }
580+
581+ static u32 pll_config_get_lnl (struct ivpu_device * vdev )
582+ {
583+ return REGB_RD32 (VPU_HW_BTRS_LNL_PLL_FREQ );
584+ }
585+
586+ static u32 pll_ratio_to_dpu_freq_mtl (u16 ratio )
587+ {
588+ return (PLL_RATIO_TO_FREQ (ratio ) * 2 ) / 3 ;
589+ }
590+
591+ static u32 pll_ratio_to_dpu_freq_lnl (u16 ratio )
592+ {
593+ return PLL_RATIO_TO_FREQ (ratio ) / 2 ;
594+ }
595+
596+ static u32 pll_ratio_to_dpu_freq (struct ivpu_device * vdev , u32 ratio )
597+ {
598+ if (ivpu_hw_btrs_gen (vdev ) == IVPU_HW_BTRS_MTL )
599+ return pll_ratio_to_dpu_freq_mtl (ratio );
600+ else
601+ return pll_ratio_to_dpu_freq_lnl (ratio );
602+ }
603+
604+ u32 ivpu_hw_btrs_dpu_max_freq_get (struct ivpu_device * vdev )
605+ {
606+ return pll_ratio_to_dpu_freq (vdev , vdev -> hw -> pll .max_ratio );
607+ }
608+
609+ u32 ivpu_hw_btrs_dpu_freq_get (struct ivpu_device * vdev )
610+ {
611+ if (ivpu_hw_btrs_gen (vdev ) == IVPU_HW_BTRS_MTL )
612+ return pll_ratio_to_dpu_freq_mtl (pll_config_get_mtl (vdev ));
613+ else
614+ return pll_ratio_to_dpu_freq_lnl (pll_config_get_lnl (vdev ));
615+ }
616+
576617/* Handler for IRQs from Buttress core (irqB) */
577618bool ivpu_hw_btrs_irq_handler_mtl (struct ivpu_device * vdev , int irq )
578619{
@@ -582,9 +623,12 @@ bool ivpu_hw_btrs_irq_handler_mtl(struct ivpu_device *vdev, int irq)
582623 if (!status )
583624 return false;
584625
585- if (REG_TEST_FLD (VPU_HW_BTRS_MTL_INTERRUPT_STAT , FREQ_CHANGE , status ))
586- ivpu_dbg (vdev , IRQ , "FREQ_CHANGE irq: %08x" ,
587- REGB_RD32 (VPU_HW_BTRS_MTL_CURRENT_PLL ));
626+ if (REG_TEST_FLD (VPU_HW_BTRS_MTL_INTERRUPT_STAT , FREQ_CHANGE , status )) {
627+ u32 pll = pll_config_get_mtl (vdev );
628+
629+ ivpu_dbg (vdev , IRQ , "FREQ_CHANGE irq, wp %08x, %lu MHz" ,
630+ pll , pll_ratio_to_dpu_freq_mtl (pll ) / HZ_PER_MHZ );
631+ }
588632
589633 if (REG_TEST_FLD (VPU_HW_BTRS_MTL_INTERRUPT_STAT , ATS_ERR , status )) {
590634 ivpu_err (vdev , "ATS_ERR irq 0x%016llx" , REGB_RD64 (VPU_HW_BTRS_MTL_ATS_ERR_LOG_0 ));
@@ -633,8 +677,12 @@ bool ivpu_hw_btrs_irq_handler_lnl(struct ivpu_device *vdev, int irq)
633677 queue_work (system_wq , & vdev -> irq_dct_work );
634678 }
635679
636- if (REG_TEST_FLD (VPU_HW_BTRS_LNL_INTERRUPT_STAT , FREQ_CHANGE , status ))
637- ivpu_dbg (vdev , IRQ , "FREQ_CHANGE irq: %08x" , REGB_RD32 (VPU_HW_BTRS_LNL_PLL_FREQ ));
680+ if (REG_TEST_FLD (VPU_HW_BTRS_LNL_INTERRUPT_STAT , FREQ_CHANGE , status )) {
681+ u32 pll = pll_config_get_lnl (vdev );
682+
683+ ivpu_dbg (vdev , IRQ , "FREQ_CHANGE irq, wp %08x, %lu MHz" ,
684+ pll , pll_ratio_to_dpu_freq_lnl (pll ) / HZ_PER_MHZ );
685+ }
638686
639687 if (REG_TEST_FLD (VPU_HW_BTRS_LNL_INTERRUPT_STAT , ATS_ERR , status )) {
640688 ivpu_err (vdev , "ATS_ERR LOG1 0x%08x ATS_ERR_LOG2 0x%08x\n" ,
@@ -717,60 +765,6 @@ void ivpu_hw_btrs_dct_set_status(struct ivpu_device *vdev, bool enable, u32 acti
717765 REGB_WR32 (VPU_HW_BTRS_LNL_PCODE_MAILBOX_STATUS , val );
718766}
719767
720- static u32 pll_ratio_to_freq_mtl (u32 ratio , u32 config )
721- {
722- u32 pll_clock = PLL_REF_CLK_FREQ * ratio ;
723- u32 cpu_clock ;
724-
725- if ((config & 0xff ) == MTL_PLL_RATIO_4_3 )
726- cpu_clock = pll_clock * 2 / 4 ;
727- else
728- cpu_clock = pll_clock * 2 / 5 ;
729-
730- return cpu_clock ;
731- }
732-
733- u32 ivpu_hw_btrs_ratio_to_freq (struct ivpu_device * vdev , u32 ratio )
734- {
735- struct ivpu_hw_info * hw = vdev -> hw ;
736-
737- if (ivpu_hw_btrs_gen (vdev ) == IVPU_HW_BTRS_MTL )
738- return pll_ratio_to_freq_mtl (ratio , hw -> config );
739- else
740- return PLL_RATIO_TO_FREQ (ratio );
741- }
742-
743- static u32 pll_freq_get_mtl (struct ivpu_device * vdev )
744- {
745- u32 pll_curr_ratio ;
746-
747- pll_curr_ratio = REGB_RD32 (VPU_HW_BTRS_MTL_CURRENT_PLL );
748- pll_curr_ratio &= VPU_HW_BTRS_MTL_CURRENT_PLL_RATIO_MASK ;
749-
750- if (!ivpu_is_silicon (vdev ))
751- return PLL_SIMULATION_FREQ ;
752-
753- return pll_ratio_to_freq_mtl (pll_curr_ratio , vdev -> hw -> config );
754- }
755-
756- static u32 pll_freq_get_lnl (struct ivpu_device * vdev )
757- {
758- u32 pll_curr_ratio ;
759-
760- pll_curr_ratio = REGB_RD32 (VPU_HW_BTRS_LNL_PLL_FREQ );
761- pll_curr_ratio &= VPU_HW_BTRS_LNL_PLL_FREQ_RATIO_MASK ;
762-
763- return PLL_RATIO_TO_FREQ (pll_curr_ratio );
764- }
765-
766- u32 ivpu_hw_btrs_pll_freq_get (struct ivpu_device * vdev )
767- {
768- if (ivpu_hw_btrs_gen (vdev ) == IVPU_HW_BTRS_MTL )
769- return pll_freq_get_mtl (vdev );
770- else
771- return pll_freq_get_lnl (vdev );
772- }
773-
774768u32 ivpu_hw_btrs_telemetry_offset_get (struct ivpu_device * vdev )
775769{
776770 if (ivpu_hw_btrs_gen (vdev ) == IVPU_HW_BTRS_MTL )
0 commit comments