hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/drivers/nvmem/rockchip-otp.c
....@@ -77,6 +77,18 @@
7777 #define OTPC_TIMEOUT_PROG 100000
7878 #define RK3568_NBYTES 2
7979
80
+#define RK3588_OTPC_AUTO_CTRL 0x04
81
+#define RK3588_OTPC_AUTO_EN 0x08
82
+#define RK3588_OTPC_INT_ST 0x84
83
+#define RK3588_OTPC_DOUT0 0x20
84
+#define RK3588_NO_SECURE_OFFSET 0x300
85
+#define RK3588_NBYTES 4
86
+#define RK3588_BURST_NUM 1
87
+#define RK3588_BURST_SHIFT 8
88
+#define RK3588_ADDR_SHIFT 16
89
+#define RK3588_AUTO_EN BIT(0)
90
+#define RK3588_RD_DONE BIT(1)
91
+
8092 #define RV1126_OTP_NVM_CEB 0x00
8193 #define RV1126_OTP_NVM_RSTB 0x04
8294 #define RV1126_OTP_NVM_ST 0x18
....@@ -144,7 +156,7 @@
144156 struct rockchip_otp {
145157 struct device *dev;
146158 void __iomem *base;
147
- struct clk_bulk_data *clks;
159
+ struct clk_bulk_data *clks;
148160 int num_clks;
149161 struct reset_control *rst;
150162 struct nvmem_config *config;
....@@ -302,7 +314,7 @@
302314 dev_err(otp->dev, "timeout during wait dp2stb\n");
303315 return ret;
304316 }
305
- /* fall through */
317
+ fallthrough;
306318 case OTPC_STANDBY:
307319 writel(OTPC_ACTIVE, otp->base + OTPC_MODE_CTRL);
308320 ret = px30s_otp_wait_status(otp, OTPC_STB2ACT_IRQ_ST);
....@@ -333,7 +345,7 @@
333345 dev_err(otp->dev, "timeout during wait act2stb\n");
334346 return ret;
335347 }
336
- /* fall through */
348
+ fallthrough;
337349 case OTPC_STANDBY:
338350 writel(OTPC_DEEP_STANDBY, otp->base + OTPC_MODE_CTRL);
339351 ret = px30s_otp_wait_status(otp, OTPC_STB2DP_IRQ_ST);
....@@ -481,6 +493,80 @@
481493 read_end:
482494 writel(0x0 | OTPC_USE_USER_MASK, otp->base + OTPC_USER_CTRL);
483495 disable_clks:
496
+ clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
497
+out:
498
+ kfree(buf);
499
+
500
+ return ret;
501
+}
502
+
503
+static int rk3588_otp_wait_status(struct rockchip_otp *otp, u32 flag)
504
+{
505
+ u32 status = 0;
506
+ int ret;
507
+
508
+ ret = readl_poll_timeout_atomic(otp->base + RK3588_OTPC_INT_ST, status,
509
+ (status & flag), 1, OTPC_TIMEOUT);
510
+ if (ret)
511
+ return ret;
512
+
513
+ /* clean int status */
514
+ writel(flag, otp->base + RK3588_OTPC_INT_ST);
515
+
516
+ return 0;
517
+}
518
+
519
+static int rk3588_otp_read(void *context, unsigned int offset, void *val,
520
+ size_t bytes)
521
+{
522
+ struct rockchip_otp *otp = context;
523
+ unsigned int addr_start, addr_end, addr_offset, addr_len;
524
+ int ret = 0, i = 0;
525
+ u32 out_value;
526
+ u8 *buf;
527
+
528
+ if (offset >= otp->data->size)
529
+ return -ENOMEM;
530
+ if (offset + bytes > otp->data->size)
531
+ bytes = otp->data->size - offset;
532
+
533
+ addr_start = rounddown(offset, RK3588_NBYTES) / RK3588_NBYTES;
534
+ addr_end = roundup(offset + bytes, RK3588_NBYTES) / RK3588_NBYTES;
535
+ addr_offset = offset % RK3588_NBYTES;
536
+ addr_len = addr_end - addr_start;
537
+ addr_start += RK3588_NO_SECURE_OFFSET;
538
+
539
+ buf = kzalloc(array3_size(addr_len, RK3588_NBYTES, sizeof(*buf)),
540
+ GFP_KERNEL);
541
+ if (!buf)
542
+ return -ENOMEM;
543
+
544
+ ret = clk_bulk_prepare_enable(otp->num_clks, otp->clks);
545
+ if (ret < 0) {
546
+ dev_err(otp->dev, "failed to prepare/enable clks\n");
547
+ goto out;
548
+ }
549
+
550
+ while (addr_len--) {
551
+ writel((addr_start << RK3588_ADDR_SHIFT) |
552
+ (RK3588_BURST_NUM << RK3588_BURST_SHIFT),
553
+ otp->base + RK3588_OTPC_AUTO_CTRL);
554
+ writel(RK3588_AUTO_EN, otp->base + RK3588_OTPC_AUTO_EN);
555
+ ret = rk3588_otp_wait_status(otp, RK3588_RD_DONE);
556
+ if (ret < 0) {
557
+ dev_err(otp->dev, "timeout during read setup\n");
558
+ goto read_end;
559
+ }
560
+
561
+ out_value = readl(otp->base + RK3588_OTPC_DOUT0);
562
+ memcpy(&buf[i], &out_value, RK3588_NBYTES);
563
+ i += RK3588_NBYTES;
564
+ addr_start++;
565
+ }
566
+
567
+ memcpy(val, buf + addr_offset, bytes);
568
+
569
+read_end:
484570 clk_bulk_disable_unprepare(otp->num_clks, otp->clks);
485571 out:
486572 kfree(buf);
....@@ -686,6 +772,17 @@
686772 .reg_read = rk3568_otp_read,
687773 };
688774
775
+static const char * const rk3562_otp_clocks[] = {
776
+ "usr", "sbpi", "apb", "arb", "phy",
777
+};
778
+
779
+static const struct rockchip_data rk3562_data = {
780
+ .size = 0x80,
781
+ .clocks = rk3562_otp_clocks,
782
+ .num_clks = ARRAY_SIZE(rk3562_otp_clocks),
783
+ .reg_read = rk3568_otp_read,
784
+};
785
+
689786 static const char * const rk3568_otp_clocks[] = {
690787 "usr", "sbpi", "apb", "phy",
691788 };
....@@ -694,6 +791,28 @@
694791 .size = 0x80,
695792 .clocks = rk3568_otp_clocks,
696793 .num_clks = ARRAY_SIZE(rk3568_otp_clocks),
794
+ .reg_read = rk3568_otp_read,
795
+};
796
+
797
+static const char * const rk3588_otp_clocks[] = {
798
+ "otpc", "apb", "arb", "phy",
799
+};
800
+
801
+static const struct rockchip_data rk3588_data = {
802
+ .size = 0x400,
803
+ .clocks = rk3588_otp_clocks,
804
+ .num_clks = ARRAY_SIZE(rk3588_otp_clocks),
805
+ .reg_read = rk3588_otp_read,
806
+};
807
+
808
+static const char * const rv1106_otp_clocks[] = {
809
+ "usr", "sbpi", "apb", "phy", "arb", "pmc",
810
+};
811
+
812
+static const struct rockchip_data rv1106_data = {
813
+ .size = 0x80,
814
+ .clocks = rv1106_otp_clocks,
815
+ .num_clks = ARRAY_SIZE(rv1106_otp_clocks),
697816 .reg_read = rk3568_otp_read,
698817 };
699818
....@@ -726,6 +845,10 @@
726845 .compatible = "rockchip,rk3308-otp",
727846 .data = (void *)&px30_data,
728847 },
848
+ {
849
+ .compatible = "rockchip,rk3308bs-otp",
850
+ .data = (void *)&px30s_data,
851
+ },
729852 #endif
730853 #ifdef CONFIG_CPU_RK3528
731854 {
....@@ -733,10 +856,28 @@
733856 .data = (void *)&rk3528_data,
734857 },
735858 #endif
859
+#ifdef CONFIG_CPU_RK3562
860
+ {
861
+ .compatible = "rockchip,rk3562-otp",
862
+ .data = (void *)&rk3562_data,
863
+ },
864
+#endif
736865 #ifdef CONFIG_CPU_RK3568
737866 {
738867 .compatible = "rockchip,rk3568-otp",
739868 .data = (void *)&rk3568_data,
869
+ },
870
+#endif
871
+#ifdef CONFIG_CPU_RK3588
872
+ {
873
+ .compatible = "rockchip,rk3588-otp",
874
+ .data = (void *)&rk3588_data,
875
+ },
876
+#endif
877
+#ifdef CONFIG_CPU_RV1106
878
+ {
879
+ .compatible = "rockchip,rv1106-otp",
880
+ .data = (void *)&rv1106_data,
740881 },
741882 #endif
742883 #ifdef CONFIG_CPU_RV1126
....@@ -749,7 +890,7 @@
749890 };
750891 MODULE_DEVICE_TABLE(of, rockchip_otp_match);
751892
752
-static int __init rockchip_otp_probe(struct platform_device *pdev)
893
+static int rockchip_otp_probe(struct platform_device *pdev)
753894 {
754895 struct device *dev = &pdev->dev;
755896 struct rockchip_otp *otp;
....@@ -762,7 +903,7 @@
762903 dev_err(dev, "failed to get match data\n");
763904 return -EINVAL;
764905 }
765
- if (soc_is_px30s())
906
+ if (soc_is_px30s() || soc_is_rk3308bs())
766907 data = &px30s_data;
767908
768909 otp = devm_kzalloc(&pdev->dev, sizeof(struct rockchip_otp),
....@@ -811,19 +952,33 @@
811952 }
812953
813954 static struct platform_driver rockchip_otp_driver = {
955
+ .probe = rockchip_otp_probe,
814956 .driver = {
815957 .name = "rockchip-otp",
816958 .of_match_table = rockchip_otp_match,
817959 },
818960 };
819961
820
-static int __init rockchip_otp_module_init(void)
962
+static int __init rockchip_otp_init(void)
821963 {
822
- return platform_driver_probe(&rockchip_otp_driver,
823
- rockchip_otp_probe);
964
+ int ret;
965
+
966
+ ret = platform_driver_register(&rockchip_otp_driver);
967
+ if (ret) {
968
+ pr_err("failed to register otp driver\n");
969
+ return ret;
970
+ }
971
+
972
+ return 0;
824973 }
825974
826
-subsys_initcall(rockchip_otp_module_init);
975
+static void __exit rockchip_otp_exit(void)
976
+{
977
+ return platform_driver_unregister(&rockchip_otp_driver);
978
+}
979
+
980
+subsys_initcall(rockchip_otp_init);
981
+module_exit(rockchip_otp_exit);
827982
828983 MODULE_DESCRIPTION("Rockchip OTP driver");
829984 MODULE_LICENSE("GPL v2");