diff --git a/drivers/rknpu/rknpu_drv.c b/drivers/rknpu/rknpu_drv.c index 30dfc38f76c9..26d10c233cc9 100644 --- a/drivers/rknpu/rknpu_drv.c +++ b/drivers/rknpu/rknpu_drv.c @@ -1107,6 +1107,66 @@ static struct devfreq_cooling_power npu_cooling_power = { }; #if KERNEL_VERSION(5, 10, 0) <= LINUX_VERSION_CODE +static int rk3588_npu_get_soc_info(struct device *dev, struct device_node *np, + int *bin, int *process) +{ + int ret = 0; + u8 value = 0; + + if (!bin) + return 0; + + if (of_property_match_string(np, "nvmem-cell-names", + "specification_serial_number") >= 0) { + ret = rockchip_nvmem_cell_read_u8(np, + "specification_serial_number", + &value); + if (ret) { + dev_err(dev, + "Failed to get specification_serial_number\n"); + return ret; + } + /* RK3588M */ + if (value == 0xd) + *bin = 1; + /* RK3588J */ + else if (value == 0xa) + *bin = 2; + } + if (*bin < 0) + *bin = 0; + dev_info(dev, "bin=%d\n", *bin); + + return ret; +} + +static int rk3588_npu_set_soc_info(struct device *dev, struct device_node *np, + int bin, int process, int volt_sel) +{ + struct opp_table *opp_table; + u32 supported_hw[2]; + + if (volt_sel < 0) + return 0; + if (bin < 0) + bin = 0; + + if (!of_property_read_bool(np, "rockchip,supported-hw")) + return 0; + + /* SoC Version */ + supported_hw[0] = BIT(bin); + /* Speed Grade */ + supported_hw[1] = BIT(volt_sel); + opp_table = dev_pm_opp_set_supported_hw(dev, supported_hw, 2); + if (IS_ERR(opp_table)) { + dev_err(dev, "failed to set supported opp\n"); + return PTR_ERR(opp_table); + } + + return 0; +} + static int rk3588_npu_set_read_margin(struct device *dev, struct rockchip_opp_info *opp_info, u32 rm) @@ -1139,6 +1199,8 @@ static int rk3588_npu_set_read_margin(struct device *dev, } static const struct rockchip_opp_data rk3588_npu_opp_data = { + .get_soc_info = rk3588_npu_get_soc_info, + .set_soc_info = rk3588_npu_set_soc_info, .set_read_margin = rk3588_npu_set_read_margin, };