plat: intel: Fix clock configuration bugs

This fixes a few issues on the Agilex clock configuration:
- Set clock manager into boot mode before configuring clock
- Fix wrong divisor used when calculating vcocalib
- PLL sync configuration should be read and then written
- Wait PLL lock after PLL sync configuration is done
- Clear interrupt bits instead of set interrupt bits after configuration

Signed-off-by: Tien Hock Loh <tien.hock.loh@intel.com>
Change-Id: I54c1dc5fe9b102e3bbc1237a92d8471173b8af70
diff --git a/plat/intel/soc/agilex/soc/agilex_clock_manager.c b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
index c6c48ba..4efd713 100644
--- a/plat/intel/soc/agilex/soc/agilex_clock_manager.c
+++ b/plat/intel/soc/agilex/soc/agilex_clock_manager.c
@@ -47,14 +47,14 @@
 	return 0;
 }
 
-uint32_t pll_source_sync_config(uint32_t pll_mem_offset)
+uint32_t pll_source_sync_config(uint32_t pll_mem_offset, uint32_t data)
 {
 	uint32_t val = 0;
 	uint32_t count = 0;
 	uint32_t req_status = 0;
 
 	val = (CLKMGR_MEM_WR | CLKMGR_MEM_REQ |
-		CLKMGR_MEM_WDAT << CLKMGR_MEM_WDAT_OFFSET | CLKMGR_MEM_ADDR);
+		(data << CLKMGR_MEM_WDAT_OFFSET) | CLKMGR_MEM_ADDR);
 	mmio_write_32(pll_mem_offset, val);
 
 	do {
@@ -89,14 +89,17 @@
 	rdata = mmio_read_32(pll_mem_offset + 0x4);
 	INFO("rdata (%x) = %x\n", pll_mem_offset + 0x4, rdata);
 
-	return 0;
+	return rdata;
 }
 
 void config_clkmgr_handoff(handoff *hoff_ptr)
 {
 	uint32_t mdiv, mscnt, hscnt;
-	uint32_t arefclk_div, drefclk_div;
+	uint32_t drefclk_div, refclk_div, rdata;
 
+	/* Set clock maanger into boot mode before running configuration */
+	mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_CTRL,
+		CLKMGR_CTRL_BOOTMODE_SET_MSK);
 	/* Bypass all mainpllgrp's clocks */
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_BYPASS, 0x7);
 	wait_fsm();
@@ -116,26 +119,24 @@
 	/* Setup main PLL dividers */
 	mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->main_pll_pllm);
 
-	arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
-			hoff_ptr->main_pll_pllglob);
 	drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
 			hoff_ptr->main_pll_pllglob);
+	refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+			hoff_ptr->main_pll_pllglob);
 
-	mscnt = 100 / (mdiv / BIT(drefclk_div));
+	mscnt = 100 / (mdiv * BIT(drefclk_div));
 	if (!mscnt)
 		mscnt = 1;
-	hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+	hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
 
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
-			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
-			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
-
-	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
-			hoff_ptr->main_pll_nocdiv);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
-			hoff_ptr->main_pll_pllglob);
+			hoff_ptr->main_pll_pllglob &
+			~CLKMGR_PLLGLOB_RST_SET_MSK);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_FDBCK,
 			hoff_ptr->main_pll_fdbck);
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_VCOCALIB,
+			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
+			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC0,
 			hoff_ptr->main_pll_pllc0);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLC1,
@@ -150,33 +151,33 @@
 			hoff_ptr->main_pll_mpuclk);
 	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCCLK,
 			hoff_ptr->main_pll_nocclk);
+	mmio_write_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_NOCDIV,
+			hoff_ptr->main_pll_nocdiv);
 
 	/* Setup peripheral PLL dividers */
 	mdiv = CLKMGR_PLLM_MDIV(hoff_ptr->per_pll_pllm);
 
-	arefclk_div = CLKMGR_PLLGLOB_AREFCLKDIV(
-			hoff_ptr->per_pll_pllglob);
 	drefclk_div = CLKMGR_PLLGLOB_DREFCLKDIV(
 			hoff_ptr->per_pll_pllglob);
+	refclk_div = CLKMGR_PLLGLOB_REFCLKDIV(
+			hoff_ptr->per_pll_pllglob);
 
-	mscnt = 100 / (mdiv / BIT(drefclk_div));
+
+	mscnt = 100 / (mdiv * BIT(drefclk_div));
 	if (!mscnt)
 		mscnt = 1;
-	hscnt = (mdiv * mscnt * BIT(drefclk_div) / arefclk_div) - 4;
+	hscnt = (mdiv * mscnt * BIT(drefclk_div) / refclk_div) - 4;
+
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
+			hoff_ptr->per_pll_pllglob &
+			~CLKMGR_PLLGLOB_RST_SET_MSK);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
+			hoff_ptr->per_pll_fdbck);
 
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_VCOCALIB,
 			CLKMGR_VCOCALIB_HSCNT_SET(hscnt) |
 			CLKMGR_VCOCALIB_MSCNT_SET(mscnt));
 
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
-			hoff_ptr->per_pll_emacctl);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
-			CLKMGR_PERPLL_GPIODIV_GPIODBCLK_SET(
-			hoff_ptr->per_pll_gpiodiv));
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLGLOB,
-			hoff_ptr->per_pll_pllglob);
-	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_FDBCK,
-			hoff_ptr->per_pll_fdbck);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC0,
 			hoff_ptr->per_pll_pllc0);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLC1,
@@ -187,6 +188,10 @@
 			hoff_ptr->per_pll_pllc3);
 	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_PLLM,
 			hoff_ptr->per_pll_pllm);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_EMACCTL,
+			hoff_ptr->per_pll_emacctl);
+	mmio_write_32(CLKMGR_PERPLL + CLKMGR_PERPLL_GPIODIV,
+			hoff_ptr->per_pll_gpiodiv);
 
 	/* Take both PLL out of reset and power up */
 	mmio_setbits_32(CLKMGR_MAINPLL + CLKMGR_MAINPLL_PLLGLOB,
@@ -196,13 +201,16 @@
 			CLKMGR_PLLGLOB_PD_SET_MSK |
 			CLKMGR_PLLGLOB_RST_SET_MSK);
 
-	wait_pll_lock();
+	rdata = pll_source_sync_read(CLKMGR_MAINPLL +
+		CLKMGR_MAINPLL_MEM);
+	pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM,
+		rdata | 0x80);
 
-	pll_source_sync_config(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
-	pll_source_sync_read(CLKMGR_MAINPLL + CLKMGR_MAINPLL_MEM);
+	rdata = pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+	pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM,
+		rdata | 0x80);
 
-	pll_source_sync_config(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
-	pll_source_sync_read(CLKMGR_PERPLL + CLKMGR_PERPLL_MEM);
+	wait_pll_lock();
 
 	/*Configure Ping Pong counters in altera group */
 	mmio_write_32(CLKMGR_ALTERA + CLKMGR_ALTERA_EMACACTR,
@@ -241,7 +249,7 @@
 
 	/* Clear loss lock  interrupt status register that */
 	/* might be set during configuration */
-	mmio_setbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
+	mmio_clrbits_32(CLKMGR_OFFSET + CLKMGR_INTRCLR,
 			CLKMGR_INTRCLR_MAINLOCKLOST_SET_MSK |
 			CLKMGR_INTRCLR_PERLOCKLOST_SET_MSK);