[lc_ctrl/dif] Add get/set functions for OTP test register
Signed-off-by: Michael Schaffner <msf@opentitan.org>
diff --git a/sw/device/lib/dif/dif_lc_ctrl.c b/sw/device/lib/dif/dif_lc_ctrl.c
index df5986b..f6d08b5 100644
--- a/sw/device/lib/dif/dif_lc_ctrl.c
+++ b/sw/device/lib/dif/dif_lc_ctrl.c
@@ -314,3 +314,35 @@
1);
return kDifLcCtrlMutexOk;
}
+
+dif_lc_ctrl_mutex_result_t dif_lc_ctrl_set_otp_test_reg(const dif_lc_ctrl_t *lc,
+ uint32_t settings) {
+ if (lc == NULL) {
+ return kDifLcCtrlMutexBadArg;
+ }
+
+ uint32_t busy = mmio_region_read32(lc->params.base_addr,
+ LC_CTRL_TRANSITION_REGWEN_REG_OFFSET);
+ if (busy == 0) {
+ return kDifLcCtrlMutexAlreadyTaken;
+ }
+
+ mmio_region_write32(lc->params.base_addr, LC_CTRL_OTP_TEST_CTRL_REG_OFFSET,
+ settings);
+
+ return kDifLcCtrlMutexOk;
+}
+
+dif_lc_ctrl_result_t dif_lc_ctrl_get_otp_test_reg(const dif_lc_ctrl_t *lc,
+ uint32_t *settings) {
+ if (lc == NULL || settings == NULL) {
+ return kDifLcCtrlBadArg;
+ }
+
+ uint32_t reg = mmio_region_read32(lc->params.base_addr,
+ LC_CTRL_OTP_TEST_CTRL_REG_OFFSET);
+
+ *settings = bitfield_field32_read(reg, LC_CTRL_OTP_TEST_CTRL_VAL_FIELD);
+
+ return kDifLcCtrlOk;
+}
diff --git a/sw/device/lib/dif/dif_lc_ctrl.h b/sw/device/lib/dif/dif_lc_ctrl.h
index 39c4d9c..b53f254 100644
--- a/sw/device/lib/dif/dif_lc_ctrl.h
+++ b/sw/device/lib/dif/dif_lc_ctrl.h
@@ -425,6 +425,28 @@
const dif_lc_ctrl_t *lc, dif_lc_ctrl_state_t state,
const dif_lc_ctrl_token_t *token);
+/**
+ * Writes settings to the vendor-specific OTP test control register.
+ *
+ * @param lc A lifecycle handle.
+ * @param settings The settings to write to the register.
+ * @return The result of the operation.
+ */
+DIF_WARN_UNUSED_RESULT
+dif_lc_ctrl_mutex_result_t dif_lc_ctrl_set_otp_test_reg(const dif_lc_ctrl_t *lc,
+ uint32_t settings);
+
+/**
+ * Reads settings from the vendor-specific OTP test control register.
+ *
+ * @param lc A lifecycle handle.
+ * @param settings Output parameter for the settings.
+ * @return The result of the operation.
+ */
+DIF_WARN_UNUSED_RESULT
+dif_lc_ctrl_result_t dif_lc_ctrl_get_otp_test_reg(const dif_lc_ctrl_t *lc,
+ uint32_t *settings);
+
#ifdef __cplusplus
} // extern "C"
#endif // __cplusplus
diff --git a/sw/device/lib/dif/dif_lc_ctrl_unittest.cc b/sw/device/lib/dif/dif_lc_ctrl_unittest.cc
index df02b83..610ebbe 100644
--- a/sw/device/lib/dif/dif_lc_ctrl_unittest.cc
+++ b/sw/device/lib/dif/dif_lc_ctrl_unittest.cc
@@ -226,5 +226,20 @@
EXPECT_EQ(dif_lc_ctrl_transition(nullptr, kDifLcCtrlStateProd, &token),
kDifLcCtrlMutexBadArg);
}
+
+class OtpTestRegTest : public LcTest {};
+
+TEST_F(OtpTestRegTest, Read) {
+ uint32_t settings_read = 0;
+ EXPECT_READ32(LC_CTRL_OTP_TEST_CTRL_REG_OFFSET, 0x5A);
+ EXPECT_EQ(dif_lc_ctrl_get_otp_test_reg(&lc_, &settings_read), kDifLcCtrlOk);
+ EXPECT_EQ(settings_read, 0x5A);
+}
+
+TEST_F(OtpTestRegTest, Write) {
+ EXPECT_READ32(LC_CTRL_TRANSITION_REGWEN_REG_OFFSET, true);
+ EXPECT_WRITE32(LC_CTRL_OTP_TEST_CTRL_REG_OFFSET, 0xA5);
+ EXPECT_EQ(dif_lc_ctrl_set_otp_test_reg(&lc_, 0xA5), kDifLcCtrlMutexOk);
+}
} // namespace
} // namespace dif_lc_ctrl_unittest