@@ -1433,6 +1433,102 @@ int cppc_set_epp_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls, bool enable)
14331433}
14341434EXPORT_SYMBOL_GPL (cppc_set_epp_perf );
14351435
1436+ /**
1437+ * cppc_get_auto_sel_caps - Read autonomous selection register.
1438+ * @cpunum : CPU from which to read register.
1439+ * @perf_caps : struct where autonomous selection register value is updated.
1440+ */
1441+ int cppc_get_auto_sel_caps (int cpunum , struct cppc_perf_caps * perf_caps )
1442+ {
1443+ struct cpc_desc * cpc_desc = per_cpu (cpc_desc_ptr , cpunum );
1444+ struct cpc_register_resource * auto_sel_reg ;
1445+ u64 auto_sel ;
1446+
1447+ if (!cpc_desc ) {
1448+ pr_debug ("No CPC descriptor for CPU:%d\n" , cpunum );
1449+ return - ENODEV ;
1450+ }
1451+
1452+ auto_sel_reg = & cpc_desc -> cpc_regs [AUTO_SEL_ENABLE ];
1453+
1454+ if (!CPC_SUPPORTED (auto_sel_reg ))
1455+ pr_warn_once ("Autonomous mode is not unsupported!\n" );
1456+
1457+ if (CPC_IN_PCC (auto_sel_reg )) {
1458+ int pcc_ss_id = per_cpu (cpu_pcc_subspace_idx , cpunum );
1459+ struct cppc_pcc_data * pcc_ss_data = NULL ;
1460+ int ret = 0 ;
1461+
1462+ if (pcc_ss_id < 0 )
1463+ return - ENODEV ;
1464+
1465+ pcc_ss_data = pcc_data [pcc_ss_id ];
1466+
1467+ down_write (& pcc_ss_data -> pcc_lock );
1468+
1469+ if (send_pcc_cmd (pcc_ss_id , CMD_READ ) >= 0 ) {
1470+ cpc_read (cpunum , auto_sel_reg , & auto_sel );
1471+ perf_caps -> auto_sel = (bool )auto_sel ;
1472+ } else {
1473+ ret = - EIO ;
1474+ }
1475+
1476+ up_write (& pcc_ss_data -> pcc_lock );
1477+
1478+ return ret ;
1479+ }
1480+
1481+ return 0 ;
1482+ }
1483+ EXPORT_SYMBOL_GPL (cppc_get_auto_sel_caps );
1484+
1485+ /**
1486+ * cppc_set_auto_sel - Write autonomous selection register.
1487+ * @cpu : CPU to which to write register.
1488+ * @enable : the desired value of autonomous selection resiter to be updated.
1489+ */
1490+ int cppc_set_auto_sel (int cpu , bool enable )
1491+ {
1492+ int pcc_ss_id = per_cpu (cpu_pcc_subspace_idx , cpu );
1493+ struct cpc_register_resource * auto_sel_reg ;
1494+ struct cpc_desc * cpc_desc = per_cpu (cpc_desc_ptr , cpu );
1495+ struct cppc_pcc_data * pcc_ss_data = NULL ;
1496+ int ret = - EINVAL ;
1497+
1498+ if (!cpc_desc ) {
1499+ pr_debug ("No CPC descriptor for CPU:%d\n" , cpu );
1500+ return - ENODEV ;
1501+ }
1502+
1503+ auto_sel_reg = & cpc_desc -> cpc_regs [AUTO_SEL_ENABLE ];
1504+
1505+ if (CPC_IN_PCC (auto_sel_reg )) {
1506+ if (pcc_ss_id < 0 ) {
1507+ pr_debug ("Invalid pcc_ss_id\n" );
1508+ return - ENODEV ;
1509+ }
1510+
1511+ if (CPC_SUPPORTED (auto_sel_reg )) {
1512+ ret = cpc_write (cpu , auto_sel_reg , enable );
1513+ if (ret )
1514+ return ret ;
1515+ }
1516+
1517+ pcc_ss_data = pcc_data [pcc_ss_id ];
1518+
1519+ down_write (& pcc_ss_data -> pcc_lock );
1520+ /* after writing CPC, transfer the ownership of PCC to platform */
1521+ ret = send_pcc_cmd (pcc_ss_id , CMD_WRITE );
1522+ up_write (& pcc_ss_data -> pcc_lock );
1523+ } else {
1524+ ret = - ENOTSUPP ;
1525+ pr_debug ("_CPC in PCC is not supported\n" );
1526+ }
1527+
1528+ return ret ;
1529+ }
1530+ EXPORT_SYMBOL_GPL (cppc_set_auto_sel );
1531+
14361532/**
14371533 * cppc_set_enable - Set to enable CPPC on the processor by writing the
14381534 * Continuous Performance Control package EnableRegister field.
@@ -1488,7 +1584,7 @@ EXPORT_SYMBOL_GPL(cppc_set_enable);
14881584int cppc_set_perf (int cpu , struct cppc_perf_ctrls * perf_ctrls )
14891585{
14901586 struct cpc_desc * cpc_desc = per_cpu (cpc_desc_ptr , cpu );
1491- struct cpc_register_resource * desired_reg ;
1587+ struct cpc_register_resource * desired_reg , * min_perf_reg , * max_perf_reg ;
14921588 int pcc_ss_id = per_cpu (cpu_pcc_subspace_idx , cpu );
14931589 struct cppc_pcc_data * pcc_ss_data = NULL ;
14941590 int ret = 0 ;
@@ -1499,6 +1595,8 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
14991595 }
15001596
15011597 desired_reg = & cpc_desc -> cpc_regs [DESIRED_PERF ];
1598+ min_perf_reg = & cpc_desc -> cpc_regs [MIN_PERF ];
1599+ max_perf_reg = & cpc_desc -> cpc_regs [MAX_PERF ];
15021600
15031601 /*
15041602 * This is Phase-I where we want to write to CPC registers
@@ -1507,7 +1605,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15071605 * Since read_lock can be acquired by multiple CPUs simultaneously we
15081606 * achieve that goal here
15091607 */
1510- if (CPC_IN_PCC (desired_reg )) {
1608+ if (CPC_IN_PCC (desired_reg ) || CPC_IN_PCC ( min_perf_reg ) || CPC_IN_PCC ( max_perf_reg ) ) {
15111609 if (pcc_ss_id < 0 ) {
15121610 pr_debug ("Invalid pcc_ss_id\n" );
15131611 return - ENODEV ;
@@ -1530,13 +1628,19 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15301628 cpc_desc -> write_cmd_status = 0 ;
15311629 }
15321630
1631+ cpc_write (cpu , desired_reg , perf_ctrls -> desired_perf );
1632+
15331633 /*
1534- * Skip writing MIN/MAX until Linux knows how to come up with
1535- * useful values.
1634+ * Only write if min_perf and max_perf not zero. Some drivers pass zero
1635+ * value to min and max perf, but they don't mean to set the zero value,
1636+ * they just don't want to write to those registers.
15361637 */
1537- cpc_write (cpu , desired_reg , perf_ctrls -> desired_perf );
1638+ if (perf_ctrls -> min_perf )
1639+ cpc_write (cpu , min_perf_reg , perf_ctrls -> min_perf );
1640+ if (perf_ctrls -> max_perf )
1641+ cpc_write (cpu , max_perf_reg , perf_ctrls -> max_perf );
15381642
1539- if (CPC_IN_PCC (desired_reg ))
1643+ if (CPC_IN_PCC (desired_reg ) || CPC_IN_PCC ( min_perf_reg ) || CPC_IN_PCC ( max_perf_reg ) )
15401644 up_read (& pcc_ss_data -> pcc_lock ); /* END Phase-I */
15411645 /*
15421646 * This is Phase-II where we transfer the ownership of PCC to Platform
@@ -1584,7 +1688,7 @@ int cppc_set_perf(int cpu, struct cppc_perf_ctrls *perf_ctrls)
15841688 * case during a CMD_READ and if there are pending writes it delivers
15851689 * the write command before servicing the read command
15861690 */
1587- if (CPC_IN_PCC (desired_reg )) {
1691+ if (CPC_IN_PCC (desired_reg ) || CPC_IN_PCC ( min_perf_reg ) || CPC_IN_PCC ( max_perf_reg ) ) {
15881692 if (down_write_trylock (& pcc_ss_data -> pcc_lock )) {/* BEGIN Phase-II */
15891693 /* Update only if there are pending write commands */
15901694 if (pcc_ss_data -> pending_pcc_write_cmd )
0 commit comments