| .. | .. |
|---|
| 17 | 17 | |
|---|
| 18 | 18 | static u32 share_count_nand; |
|---|
| 19 | 19 | static u32 share_count_media; |
|---|
| 20 | +static u32 share_count_usb; |
|---|
| 20 | 21 | |
|---|
| 21 | 22 | static const char * const pll_ref_sels[] = { "osc_24m", "dummy", "dummy", "dummy", }; |
|---|
| 22 | 23 | static const char * const audio_pll1_bypass_sels[] = {"audio_pll1", "audio_pll1_ref_sel", }; |
|---|
| .. | .. |
|---|
| 179 | 180 | static const char * const imx8mp_sai3_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", |
|---|
| 180 | 181 | "video_pll1_out", "sys_pll1_133m", "osc_hdmi", |
|---|
| 181 | 182 | "clk_ext3", "clk_ext4", }; |
|---|
| 182 | | - |
|---|
| 183 | | -static const char * const imx8mp_sai4_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", |
|---|
| 184 | | - "video_pll1_out", "sys_pll1_133m", "osc_hdmi", |
|---|
| 185 | | - "clk_ext1", "clk_ext2", }; |
|---|
| 186 | 183 | |
|---|
| 187 | 184 | static const char * const imx8mp_sai5_sels[] = {"osc_24m", "audio_pll1_out", "audio_pll2_out", |
|---|
| 188 | 185 | "video_pll1_out", "sys_pll1_133m", "osc_hdmi", |
|---|
| .. | .. |
|---|
| 362 | 359 | "clk_ext2", "audio_pll2_out", |
|---|
| 363 | 360 | "video_pll1_out", }; |
|---|
| 364 | 361 | |
|---|
| 365 | | -static const char * const imx8mp_media_disp1_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", |
|---|
| 362 | +static const char * const imx8mp_media_disp_pix_sels[] = {"osc_24m", "video_pll1_out", "audio_pll2_out", |
|---|
| 366 | 363 | "audio_pll1_out", "sys_pll1_800m", |
|---|
| 367 | 364 | "sys_pll2_1000m", "sys_pll3_out", "clk_ext4", }; |
|---|
| 368 | 365 | |
|---|
| .. | .. |
|---|
| 411 | 408 | |
|---|
| 412 | 409 | static const char * const imx8mp_dram_core_sels[] = {"dram_pll_out", "dram_alt_root", }; |
|---|
| 413 | 410 | |
|---|
| 411 | +static const char * const imx8mp_clkout_sels[] = {"audio_pll1_out", "audio_pll2_out", "video_pll1_out", |
|---|
| 412 | + "dummy", "dummy", "gpu_pll_out", "vpu_pll_out", |
|---|
| 413 | + "arm_pll_out", "sys_pll1", "sys_pll2", "sys_pll3", |
|---|
| 414 | + "dummy", "dummy", "osc_24m", "dummy", "osc_32k"}; |
|---|
| 415 | + |
|---|
| 414 | 416 | static struct clk_hw **hws; |
|---|
| 415 | 417 | static struct clk_hw_onecell_data *clk_hw_data; |
|---|
| 416 | 418 | |
|---|
| .. | .. |
|---|
| 419 | 421 | struct device *dev = &pdev->dev; |
|---|
| 420 | 422 | struct device_node *np = dev->of_node; |
|---|
| 421 | 423 | void __iomem *anatop_base, *ccm_base; |
|---|
| 424 | + int err; |
|---|
| 422 | 425 | |
|---|
| 423 | 426 | np = of_find_compatible_node(NULL, NULL, "fsl,imx8mp-anatop"); |
|---|
| 424 | | - anatop_base = of_iomap(np, 0); |
|---|
| 427 | + anatop_base = devm_of_iomap(dev, np, 0, NULL); |
|---|
| 425 | 428 | of_node_put(np); |
|---|
| 426 | | - if (WARN_ON(!anatop_base)) |
|---|
| 427 | | - return -ENOMEM; |
|---|
| 429 | + if (WARN_ON(IS_ERR(anatop_base))) |
|---|
| 430 | + return PTR_ERR(anatop_base); |
|---|
| 428 | 431 | |
|---|
| 429 | 432 | np = dev->of_node; |
|---|
| 430 | 433 | ccm_base = devm_platform_ioremap_resource(pdev, 0); |
|---|
| 431 | | - if (WARN_ON(IS_ERR(ccm_base))) { |
|---|
| 432 | | - iounmap(anatop_base); |
|---|
| 434 | + if (WARN_ON(IS_ERR(ccm_base))) |
|---|
| 433 | 435 | return PTR_ERR(ccm_base); |
|---|
| 434 | | - } |
|---|
| 435 | 436 | |
|---|
| 436 | | - clk_hw_data = kzalloc(struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); |
|---|
| 437 | | - if (WARN_ON(!clk_hw_data)) { |
|---|
| 438 | | - iounmap(anatop_base); |
|---|
| 437 | + clk_hw_data = devm_kzalloc(dev, struct_size(clk_hw_data, hws, IMX8MP_CLK_END), GFP_KERNEL); |
|---|
| 438 | + if (WARN_ON(!clk_hw_data)) |
|---|
| 439 | 439 | return -ENOMEM; |
|---|
| 440 | | - } |
|---|
| 441 | 440 | |
|---|
| 442 | 441 | clk_hw_data->num = IMX8MP_CLK_END; |
|---|
| 443 | 442 | hws = clk_hw_data->hws; |
|---|
| .. | .. |
|---|
| 532 | 531 | hws[IMX8MP_SYS_PLL2_500M] = imx_clk_hw_fixed_factor("sys_pll2_500m", "sys_pll2_500m_cg", 1, 2); |
|---|
| 533 | 532 | hws[IMX8MP_SYS_PLL2_1000M] = imx_clk_hw_fixed_factor("sys_pll2_1000m", "sys_pll2_out", 1, 1); |
|---|
| 534 | 533 | |
|---|
| 534 | + hws[IMX8MP_CLK_CLKOUT1_SEL] = imx_clk_hw_mux2("clkout1_sel", anatop_base + 0x128, 4, 4, |
|---|
| 535 | + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); |
|---|
| 536 | + hws[IMX8MP_CLK_CLKOUT1_DIV] = imx_clk_hw_divider("clkout1_div", "clkout1_sel", anatop_base + 0x128, 0, 4); |
|---|
| 537 | + hws[IMX8MP_CLK_CLKOUT1] = imx_clk_hw_gate("clkout1", "clkout1_div", anatop_base + 0x128, 8); |
|---|
| 538 | + hws[IMX8MP_CLK_CLKOUT2_SEL] = imx_clk_hw_mux2("clkout2_sel", anatop_base + 0x128, 20, 4, |
|---|
| 539 | + imx8mp_clkout_sels, ARRAY_SIZE(imx8mp_clkout_sels)); |
|---|
| 540 | + hws[IMX8MP_CLK_CLKOUT2_DIV] = imx_clk_hw_divider("clkout2_div", "clkout2_sel", anatop_base + 0x128, 16, 4); |
|---|
| 541 | + hws[IMX8MP_CLK_CLKOUT2] = imx_clk_hw_gate("clkout2", "clkout2_div", anatop_base + 0x128, 24); |
|---|
| 542 | + |
|---|
| 535 | 543 | hws[IMX8MP_CLK_A53_DIV] = imx8m_clk_hw_composite_core("arm_a53_div", imx8mp_a53_sels, ccm_base + 0x8000); |
|---|
| 536 | 544 | hws[IMX8MP_CLK_A53_SRC] = hws[IMX8MP_CLK_A53_DIV]; |
|---|
| 537 | 545 | hws[IMX8MP_CLK_A53_CG] = hws[IMX8MP_CLK_A53_DIV]; |
|---|
| .. | .. |
|---|
| 566 | 574 | hws[IMX8MP_CLK_AHB] = imx8m_clk_hw_composite_bus_critical("ahb_root", imx8mp_ahb_sels, ccm_base + 0x9000); |
|---|
| 567 | 575 | hws[IMX8MP_CLK_AUDIO_AHB] = imx8m_clk_hw_composite_bus("audio_ahb", imx8mp_audio_ahb_sels, ccm_base + 0x9100); |
|---|
| 568 | 576 | hws[IMX8MP_CLK_MIPI_DSI_ESC_RX] = imx8m_clk_hw_composite_bus("mipi_dsi_esc_rx", imx8mp_mipi_dsi_esc_rx_sels, ccm_base + 0x9200); |
|---|
| 577 | + hws[IMX8MP_CLK_MEDIA_DISP2_PIX] = imx8m_clk_hw_composite("media_disp2_pix", imx8mp_media_disp_pix_sels, ccm_base + 0x9300); |
|---|
| 569 | 578 | |
|---|
| 570 | 579 | hws[IMX8MP_CLK_IPG_ROOT] = imx_clk_hw_divider2("ipg_root", "ahb_root", ccm_base + 0x9080, 0, 1); |
|---|
| 571 | 580 | hws[IMX8MP_CLK_IPG_AUDIO_ROOT] = imx_clk_hw_divider2("ipg_audio_root", "audio_ahb", ccm_base + 0x9180, 0, 1); |
|---|
| .. | .. |
|---|
| 583 | 592 | hws[IMX8MP_CLK_SAI1] = imx8m_clk_hw_composite("sai1", imx8mp_sai1_sels, ccm_base + 0xa580); |
|---|
| 584 | 593 | hws[IMX8MP_CLK_SAI2] = imx8m_clk_hw_composite("sai2", imx8mp_sai2_sels, ccm_base + 0xa600); |
|---|
| 585 | 594 | hws[IMX8MP_CLK_SAI3] = imx8m_clk_hw_composite("sai3", imx8mp_sai3_sels, ccm_base + 0xa680); |
|---|
| 586 | | - hws[IMX8MP_CLK_SAI4] = imx8m_clk_hw_composite("sai4", imx8mp_sai4_sels, ccm_base + 0xa700); |
|---|
| 587 | 595 | hws[IMX8MP_CLK_SAI5] = imx8m_clk_hw_composite("sai5", imx8mp_sai5_sels, ccm_base + 0xa780); |
|---|
| 588 | 596 | hws[IMX8MP_CLK_SAI6] = imx8m_clk_hw_composite("sai6", imx8mp_sai6_sels, ccm_base + 0xa800); |
|---|
| 589 | 597 | hws[IMX8MP_CLK_ENET_QOS] = imx8m_clk_hw_composite("enet_qos", imx8mp_enet_qos_sels, ccm_base + 0xa880); |
|---|
| .. | .. |
|---|
| 630 | 638 | hws[IMX8MP_CLK_USDHC3] = imx8m_clk_hw_composite("usdhc3", imx8mp_usdhc3_sels, ccm_base + 0xbc80); |
|---|
| 631 | 639 | hws[IMX8MP_CLK_MEDIA_CAM1_PIX] = imx8m_clk_hw_composite("media_cam1_pix", imx8mp_media_cam1_pix_sels, ccm_base + 0xbd00); |
|---|
| 632 | 640 | hws[IMX8MP_CLK_MEDIA_MIPI_PHY1_REF] = imx8m_clk_hw_composite("media_mipi_phy1_ref", imx8mp_media_mipi_phy1_ref_sels, ccm_base + 0xbd80); |
|---|
| 633 | | - hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp1_pix_sels, ccm_base + 0xbe00); |
|---|
| 641 | + hws[IMX8MP_CLK_MEDIA_DISP1_PIX] = imx8m_clk_hw_composite("media_disp1_pix", imx8mp_media_disp_pix_sels, ccm_base + 0xbe00); |
|---|
| 634 | 642 | hws[IMX8MP_CLK_MEDIA_CAM2_PIX] = imx8m_clk_hw_composite("media_cam2_pix", imx8mp_media_cam2_pix_sels, ccm_base + 0xbe80); |
|---|
| 635 | 643 | hws[IMX8MP_CLK_MEDIA_LDB] = imx8m_clk_hw_composite("media_ldb", imx8mp_media_ldb_sels, ccm_base + 0xbf00); |
|---|
| 636 | 644 | hws[IMX8MP_CLK_MEMREPAIR] = imx8m_clk_hw_composite_critical("mem_repair", imx8mp_memrepair_sels, ccm_base + 0xbf80); |
|---|
| .. | .. |
|---|
| 691 | 699 | hws[IMX8MP_CLK_UART2_ROOT] = imx_clk_hw_gate4("uart2_root_clk", "uart2", ccm_base + 0x44a0, 0); |
|---|
| 692 | 700 | hws[IMX8MP_CLK_UART3_ROOT] = imx_clk_hw_gate4("uart3_root_clk", "uart3", ccm_base + 0x44b0, 0); |
|---|
| 693 | 701 | hws[IMX8MP_CLK_UART4_ROOT] = imx_clk_hw_gate4("uart4_root_clk", "uart4", ccm_base + 0x44c0, 0); |
|---|
| 694 | | - hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate4("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0); |
|---|
| 702 | + hws[IMX8MP_CLK_USB_ROOT] = imx_clk_hw_gate2_shared2("usb_root_clk", "hsio_axi", ccm_base + 0x44d0, 0, &share_count_usb); |
|---|
| 703 | + hws[IMX8MP_CLK_USB_SUSP] = imx_clk_hw_gate2_shared2("usb_suspend_clk", "osc_32k", ccm_base + 0x44d0, 0, &share_count_usb); |
|---|
| 695 | 704 | hws[IMX8MP_CLK_USB_PHY_ROOT] = imx_clk_hw_gate4("usb_phy_root_clk", "usb_phy_ref", ccm_base + 0x44f0, 0); |
|---|
| 696 | 705 | hws[IMX8MP_CLK_USDHC1_ROOT] = imx_clk_hw_gate4("usdhc1_root_clk", "usdhc1", ccm_base + 0x4510, 0); |
|---|
| 697 | 706 | hws[IMX8MP_CLK_USDHC2_ROOT] = imx_clk_hw_gate4("usdhc2_root_clk", "usdhc2", ccm_base + 0x4520, 0); |
|---|
| .. | .. |
|---|
| 726 | 735 | |
|---|
| 727 | 736 | imx_check_clk_hws(hws, IMX8MP_CLK_END); |
|---|
| 728 | 737 | |
|---|
| 729 | | - of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
|---|
| 738 | + err = of_clk_add_hw_provider(np, of_clk_hw_onecell_get, clk_hw_data); |
|---|
| 739 | + if (err < 0) { |
|---|
| 740 | + dev_err(dev, "failed to register hws for i.MX8MP\n"); |
|---|
| 741 | + imx_unregister_hw_clocks(hws, IMX8MP_CLK_END); |
|---|
| 742 | + return err; |
|---|
| 743 | + } |
|---|
| 730 | 744 | |
|---|
| 731 | 745 | imx_register_uart_clocks(4); |
|---|
| 732 | 746 | |
|---|