diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index e07a9cf80e..6e542353fe 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -48,6 +48,15 @@ config FPGA_INTEL_SDM_MAILBOX
 	  Enable FPGA driver for writing full bitstream into Intel FPGA
 	  devices through SDM (Secure Device Manager) Mailbox.
 
+config FPGA_INTEL_PR
+	bool "Enable Intel FPGA Partial Reconfiguration driver"
+	depends on FPGA_ALTERA
+	help
+	  Say Y here to enable the Intel FPGA Partial Reconfiguration driver
+
+	  This provides basic functionality for partial reconfiguration which
+	  include the freeze controller support.
+
 config FPGA_XILINX
 	bool "Enable Xilinx FPGA drivers"
 	select FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 83243fb107..2eff387100 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -22,4 +22,5 @@ obj-$(CONFIG_FPGA_STRATIX_V) += stratixv.o
 obj-$(CONFIG_FPGA_SOCFPGA) += socfpga.o
 obj-$(CONFIG_TARGET_SOCFPGA_GEN5) += socfpga_gen5.o
 obj-$(CONFIG_TARGET_SOCFPGA_ARRIA10) += socfpga_arria10.o
+obj-$(CONFIG_FPGA_INTEL_PR) += intel_pr.o
 endif
diff --git a/drivers/fpga/intel_pr.c b/drivers/fpga/intel_pr.c
new file mode 100644
index 0000000000..05f2092600
--- /dev/null
+++ b/drivers/fpga/intel_pr.c
@@ -0,0 +1,141 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2017-2018 Intel Corporation <www.intel.com>
+ *
+ */
+
+#include <common.h>
+#include <command.h>
+#include <errno.h>
+#include <wait_bit.h>
+#include <asm/global_data.h>
+#include <asm/io.h>
+#include <linux/bitops.h>
+#include <linux/libfdt.h>
+#include <fdtdec.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define FREEZE_CSR_STATUS_OFFSET		0
+#define FREEZE_CSR_CTRL_OFFSET			4
+#define FREEZE_CSR_ILLEGAL_REQ_OFFSET		8
+#define FREEZE_CSR_REG_VERSION			12
+
+#define FREEZE_CSR_STATUS_FREEZE_REQ_DONE	BIT(0)
+#define FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE	BIT(1)
+
+#define FREEZE_CSR_CTRL_FREEZE_REQ		BIT(0)
+#define FREEZE_CSR_CTRL_RESET_REQ		BIT(1)
+#define FREEZE_CSR_CTRL_UNFREEZE_REQ		BIT(2)
+
+#define FREEZE_TIMEOUT				20000
+
+static int intel_get_freeze_br_addr(fdt_addr_t *addr, unsigned int region)
+{
+	int offset;
+	char freeze_br[12];
+
+	snprintf(freeze_br, sizeof(freeze_br), "freeze_br%d", region);
+
+	const char *alias = fdt_get_alias(gd->fdt_blob, freeze_br);
+
+	if (!alias) {
+		printf("alias %s not found in dts\n", freeze_br);
+		return -ENODEV;
+	}
+
+	offset = fdt_path_offset(gd->fdt_blob, alias);
+	if (offset < 0) {
+		printf("%s not found in dts\n", alias);
+		return -ENODEV;
+	}
+
+	*addr = fdtdec_get_addr(gd->fdt_blob, offset, "reg");
+	if (*addr == FDT_ADDR_T_NONE) {
+		printf("%s has no 'reg' property!\n", freeze_br);
+		return -ENXIO;
+	}
+
+	return 0;
+}
+
+static int intel_freeze_br_do_freeze(unsigned int region)
+{
+	u32 status;
+	int ret;
+	fdt_addr_t addr;
+
+	ret = intel_get_freeze_br_addr(&addr, region);
+	if (ret)
+		return ret;
+
+	status = readl(addr + FREEZE_CSR_STATUS_OFFSET);
+
+	if (status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE)
+		return 0;
+	else if (!(status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE))
+		return -EINVAL;
+
+	writel(FREEZE_CSR_CTRL_FREEZE_REQ, addr + FREEZE_CSR_CTRL_OFFSET);
+
+	return wait_for_bit_le32((const u32 *)(addr +
+				 FREEZE_CSR_STATUS_OFFSET),
+				 FREEZE_CSR_STATUS_FREEZE_REQ_DONE, true,
+				 FREEZE_TIMEOUT, false);
+}
+
+static int intel_freeze_br_do_unfreeze(unsigned int region)
+{
+	u32 status;
+	int ret;
+	fdt_addr_t addr;
+
+	ret = intel_get_freeze_br_addr(&addr, region);
+	if (ret)
+		return ret;
+
+	status = readl(addr + FREEZE_CSR_STATUS_OFFSET);
+
+	if (status & FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE)
+		return 0;
+	else if (!(status & FREEZE_CSR_STATUS_FREEZE_REQ_DONE))
+		return -EINVAL;
+
+	writel(FREEZE_CSR_CTRL_UNFREEZE_REQ, addr + FREEZE_CSR_CTRL_OFFSET);
+
+	return wait_for_bit_le32((const u32 *)(addr +
+				 FREEZE_CSR_STATUS_OFFSET),
+				 FREEZE_CSR_STATUS_UNFREEZE_REQ_DONE, true,
+				 FREEZE_TIMEOUT, false);
+}
+
+static int do_pr(struct cmd_tbl *cmdtp, int flag, int argc, char * const argv[])
+{
+	const char *cmd;
+	char *region;
+	unsigned int region_num = 0;
+
+	if (argc != 2 && argc != 3)
+		return CMD_RET_USAGE;
+
+	cmd = argv[1];
+	if (argc == 3)
+		region_num = simple_strtoul(argv[2], &region, 0);
+
+	if (strcmp(cmd, "start") == 0)
+		return intel_freeze_br_do_freeze(region_num);
+	else if (strcmp(cmd, "end") == 0)
+		return intel_freeze_br_do_unfreeze(region_num);
+
+	return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+	pr, 3, 1, do_pr,
+	"SoCFPGA partial reconfiguration control",
+	"start [region] - Start the partial reconfiguration by freeze the\n"
+	"PR region\n"
+	"end [region] - End the partial reconfiguration by unfreeze the PR\n"
+	"region\n"
+	""
+);
