From e4161d95a4b84b83e9769ca60eeb093977d1afaf Mon Sep 17 00:00:00 2001 From: Michael Bishop Date: Fri, 2 Aug 2024 05:03:11 -0300 Subject: [PATCH] partially fix aarch64 BE on the zero2w --- drivers/clk/bcm/clk-raspberrypi.c | 10 ++++ drivers/firmware/raspberrypi.c | 22 ++++++--- drivers/hwmon/raspberrypi-hwmon.c | 3 +- drivers/mmc/host/bcm2835-sdhost.c | 10 ++-- drivers/pmdomain/bcm/raspberrypi-power.c | 6 +-- drivers/video/fbdev/bcm2708_fb.c | 62 +++++++++++++++--------- 6 files changed, 72 insertions(+), 41 deletions(-) diff --git a/drivers/clk/bcm/clk-raspberrypi.c b/drivers/clk/bcm/clk-raspberrypi.c index 9b331f249a9823..7ea0dd21732d3c 100644 --- a/drivers/clk/bcm/clk-raspberrypi.c +++ b/drivers/clk/bcm/clk-raspberrypi.c @@ -198,6 +198,8 @@ static int raspberrypi_fw_is_prepared(struct clk_hw *hw) if (ret) return 0; + val = le32_to_cpu(val); + return !!(val & RPI_FIRMWARE_STATE_ENABLE_BIT); } @@ -215,6 +217,8 @@ static unsigned long raspberrypi_fw_get_rate(struct clk_hw *hw, if (ret) return 0; + val = le32_to_cpu(val); + return val; } @@ -310,6 +314,9 @@ static struct clk_hw *raspberrypi_clk_register(struct raspberrypi_clk *rpi, return ERR_PTR(ret); } + min_rate = le32_to_cpu(min_rate); + max_rate = le32_to_cpu(max_rate); + ret = devm_clk_hw_register(rpi->dev, &data->hw); if (ret) return ERR_PTR(ret); @@ -370,6 +377,9 @@ static int raspberrypi_discover_clocks(struct raspberrypi_clk *rpi, return ret; while (clks->id) { + clks->id = le32_to_cpu(clks->id); + clks->parent = le32_to_cpu(clks->parent); + struct raspberrypi_clk_variant *variant; if (clks->id >= RPI_FIRMWARE_NUM_CLK_ID) { diff --git a/drivers/firmware/raspberrypi.c b/drivers/firmware/raspberrypi.c index 869d542304e89f..3b92b72c1f6c85 100644 --- a/drivers/firmware/raspberrypi.c +++ b/drivers/firmware/raspberrypi.c @@ -109,24 +109,27 @@ int rpi_firmware_property_list(struct rpi_firmware *fw, /* The firmware will error out without parsing in this case. */ WARN_ON(size >= 1024 * 1024); - buf[0] = size; - buf[1] = RPI_FIRMWARE_STATUS_REQUEST; + buf[0] = cpu_to_le32(size); + buf[1] = cpu_to_le32(RPI_FIRMWARE_STATUS_REQUEST); memcpy(&buf[2], data, tag_size); - buf[size / 4 - 1] = RPI_FIRMWARE_PROPERTY_END; + buf[size / 4 - 1] = cpu_to_le32(RPI_FIRMWARE_PROPERTY_END); + + //for (int i=0; i < (size/4); i++) printk(" 0x%x ", buf[i]); + wmb(); ret = rpi_firmware_transaction(fw, MBOX_CHAN_PROPERTY, bus_addr); rmb(); memcpy(data, &buf[2], tag_size); - if (ret == 0 && buf[1] != RPI_FIRMWARE_STATUS_SUCCESS) { + if (ret == 0 && le32_to_cpu(buf[1]) != RPI_FIRMWARE_STATUS_SUCCESS) { /* * The tag name here might not be the one causing the * error, if there were multiple tags in the request. * But single-tag is the most common, so go with it. */ dev_err(fw->cl.dev, "Request 0x%08x returned status 0x%08x\n", - buf[2], buf[1]); + le32_to_cpu(buf[2]), le32_to_cpu(buf[1])); ret = -EINVAL; } @@ -167,8 +170,8 @@ int rpi_firmware_property(struct rpi_firmware *fw, return -ENOMEM; header = data; - header->tag = tag; - header->buf_size = buf_size; + header->tag = cpu_to_le32(tag); + header->buf_size = cpu_to_le32(buf_size); header->req_resp_size = 0; memcpy(data + sizeof(*header), tag_data, buf_size); @@ -272,10 +275,11 @@ rpi_firmware_print_firmware_revision(struct rpi_firmware *fw) return; /* This is not compatible with y2038 */ - date_and_time = packet; + date_and_time = le32_to_cpu(packet); ret = rpi_firmware_property(fw, RPI_FIRMWARE_GET_FIRMWARE_VARIANT, &variant, sizeof(variant)); + variant = le32_to_cpu(variant); if (!ret) { if (variant >= ARRAY_SIZE(variant_strs)) @@ -299,6 +303,8 @@ rpi_firmware_print_firmware_hash(struct rpi_firmware *fw) if (ret) return; + for (int i=0; i<5; i++) hash[i] = le32_to_cpu(hash[i]); + dev_info(fw->cl.dev, "Firmware hash is %08x%08x%08x%08x%08x\n", hash[0], hash[1], hash[2], hash[3], hash[4]); diff --git a/drivers/hwmon/raspberrypi-hwmon.c b/drivers/hwmon/raspberrypi-hwmon.c index 65cc52e47db081..9ecff45e4fa43b 100644 --- a/drivers/hwmon/raspberrypi-hwmon.c +++ b/drivers/hwmon/raspberrypi-hwmon.c @@ -31,7 +31,7 @@ static void rpi_firmware_get_throttled(struct rpi_hwmon_data *data) int ret; /* Request firmware to clear sticky bits */ - value = 0xffff; + value = cpu_to_le32(0xffff); ret = rpi_firmware_property(data->fw, RPI_FIRMWARE_GET_THROTTLED, &value, sizeof(value)); @@ -40,6 +40,7 @@ static void rpi_firmware_get_throttled(struct rpi_hwmon_data *data) ret); return; } + value = le32_to_cpu(value); new_uv = value & UNDERVOLTAGE_STICKY_BIT; old_uv = data->last_throttled & UNDERVOLTAGE_STICKY_BIT; diff --git a/drivers/mmc/host/bcm2835-sdhost.c b/drivers/mmc/host/bcm2835-sdhost.c index 8e95a9df2f8812..a63a436cdcb36d 100644 --- a/drivers/mmc/host/bcm2835-sdhost.c +++ b/drivers/mmc/host/bcm2835-sdhost.c @@ -1568,13 +1568,13 @@ void bcm2835_sdhost_set_clock(struct bcm2835_host *host, unsigned int clock) host->mmc->actual_clock = 0; if (host->firmware_sets_cdiv) { - u32 msg[3] = { clock, 0, 0 }; + u32 msg[3] = { cpu_to_le32(clock), 0, 0 }; rpi_firmware_property(host->fw, RPI_FIRMWARE_SET_SDHOST_CLOCK, &msg, sizeof(msg)); - clock = max(msg[1], msg[2]); + clock = max(le32_to_cpu(msg[1]), le32_to_cpu(msg[2])); spin_lock_irqsave(&host->lock, flags); } else { spin_lock_irqsave(&host->lock, flags); @@ -2142,14 +2142,14 @@ static int bcm2835_sdhost_probe(struct platform_device *pdev) mmc->caps |= MMC_CAP_4_BIT_DATA; msg[0] = 0; - msg[1] = ~0; - msg[2] = ~0; + msg[1] = cpu_to_le32(~0); + msg[2] = cpu_to_le32(~0); rpi_firmware_property(host->fw, RPI_FIRMWARE_SET_SDHOST_CLOCK, &msg, sizeof(msg)); - host->firmware_sets_cdiv = (msg[1] != ~0); + host->firmware_sets_cdiv = (le32_to_cpu(msg[1]) != ~0); platform_set_drvdata(pdev, host); diff --git a/drivers/pmdomain/bcm/raspberrypi-power.c b/drivers/pmdomain/bcm/raspberrypi-power.c index 06196ebfe03b03..48cb5f1b7a398c 100644 --- a/drivers/pmdomain/bcm/raspberrypi-power.c +++ b/drivers/pmdomain/bcm/raspberrypi-power.c @@ -141,14 +141,14 @@ rpi_has_new_domain_support(struct rpi_power_domains *rpi_domains) struct rpi_power_domain_packet packet; int ret; - packet.domain = RPI_POWER_DOMAIN_ARM; - packet.on = ~0; + packet.domain = cpu_to_le32(RPI_POWER_DOMAIN_ARM); + packet.on = cpu_to_le32(~0); ret = rpi_firmware_property(rpi_domains->fw, RPI_FIRMWARE_GET_DOMAIN_STATE, &packet, sizeof(packet)); - return ret == 0 && packet.on != ~0; + return ret == 0 && le32_to_cpu(packet.on) != ~0; } static int rpi_power_probe(struct platform_device *pdev) diff --git a/drivers/video/fbdev/bcm2708_fb.c b/drivers/video/fbdev/bcm2708_fb.c index 4732cb18d792f9..f3940ace347f5c 100644 --- a/drivers/video/fbdev/bcm2708_fb.c +++ b/drivers/video/fbdev/bcm2708_fb.c @@ -215,7 +215,7 @@ static int bcm2708_fb_debugfs_init(struct bcm2708_fb *fb) static void set_display_num(struct bcm2708_fb *fb) { if (fb && fb->fbdev && fb->fbdev->firmware_supports_multifb) { - u32 tmp = fb->display_settings.display_num; + u32 tmp = cpu_to_le32(fb->display_settings.display_num); if (rpi_firmware_property(fb->fbdev->fw, RPI_FIRMWARE_FRAMEBUFFER_SET_DISPLAY_NUM, @@ -350,22 +350,22 @@ static int bcm2708_fb_set_par(struct fb_info *info) { struct bcm2708_fb *fb = to_bcm2708(info); struct fb_alloc_tags fbinfo = { - .tag1 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT, - 8, 0, }, - .xres = info->var.xres, - .yres = info->var.yres, - .tag2 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT, - 8, 0, }, - .xres_virtual = info->var.xres_virtual, - .yres_virtual = info->var.yres_virtual, - .tag3 = { RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH, 4, 0 }, - .bpp = info->var.bits_per_pixel, - .tag4 = { RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET, 8, 0 }, - .xoffset = info->var.xoffset, - .yoffset = info->var.yoffset, - .tag5 = { RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE, 8, 0 }, + .tag1 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_SET_PHYSICAL_WIDTH_HEIGHT), + cpu_to_le32(8), 0, }, + .xres = cpu_to_le32(info->var.xres), + .yres = cpu_to_le32(info->var.yres), + .tag2 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_WIDTH_HEIGHT), + cpu_to_le32(8), 0, }, + .xres_virtual = cpu_to_le32(info->var.xres_virtual), + .yres_virtual = cpu_to_le32(info->var.yres_virtual), + .tag3 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_SET_DEPTH), cpu_to_le32(4), 0 }, + .bpp = cpu_to_le32(info->var.bits_per_pixel), + .tag4 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_SET_VIRTUAL_OFFSET), cpu_to_le32(8), 0 }, + .xoffset = cpu_to_le32(info->var.xoffset), + .yoffset = cpu_to_le32(info->var.yoffset), + .tag5 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_ALLOCATE), cpu_to_le32(8), 0 }, /* base and screen_size will be initialised later */ - .tag6 = { RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH, 4, 0 }, + .tag6 = { cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_SET_PITCH), cpu_to_le32(4), 0 }, /* pitch will be initialised later */ }; int ret, image_size; @@ -397,6 +397,7 @@ static int bcm2708_fb_set_par(struct fb_info *info) fb->dma_addr = 0; } + printk(KERN_ERR"allocating %d bytes\n", image_size); fb->cpuaddr = dma_alloc_coherent(info->device, image_size, &fb->dma_addr, GFP_KERNEL); @@ -409,13 +410,13 @@ static int bcm2708_fb_set_par(struct fb_info *info) } if (fb->cpuaddr) { - fbinfo.base = fb->dma_addr; - fbinfo.screen_size = image_size; - fbinfo.pitch = (info->var.xres * info->var.bits_per_pixel) >> 3; + fbinfo.base = cpu_to_le32(fb->dma_addr); + fbinfo.screen_size = cpu_to_le32(image_size); + fbinfo.pitch = cpu_to_le32((info->var.xres * info->var.bits_per_pixel) >> 3); ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, sizeof(fbinfo)); - if (ret || fbinfo.base != fb->dma_addr) { + if (ret || le32_to_cpu(fbinfo.base) != fb->dma_addr) { /* Firmware either failed, or assigned a different base * address (ie it doesn't support being passed an FB * allocation). @@ -442,7 +443,7 @@ static int bcm2708_fb_set_par(struct fb_info *info) */ fbinfo.base = 0; fbinfo.screen_size = 0; - fbinfo.tag6.tag = RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH; + fbinfo.tag6.tag = cpu_to_le32(RPI_FIRMWARE_FRAMEBUFFER_GET_PITCH); fbinfo.pitch = 0; ret = rpi_firmware_property_list(fb->fbdev->fw, &fbinfo, @@ -460,6 +461,14 @@ static int bcm2708_fb_set_par(struct fb_info *info) else fb->fb.fix.visual = FB_VISUAL_TRUECOLOR; + fbinfo.base = le32_to_cpu(fbinfo.base); + fbinfo.bpp = le32_to_cpu(fbinfo.bpp); + fbinfo.pitch = le32_to_cpu(fbinfo.pitch); + fbinfo.screen_size = le32_to_cpu(fbinfo.screen_size); + fbinfo.xres = le32_to_cpu(fbinfo.xres); + fbinfo.yres = le32_to_cpu(fbinfo.yres); + fbinfo.yres_virtual = le32_to_cpu(fbinfo.yres_virtual); + fb->fb.fix.line_length = fbinfo.pitch; fbinfo.base |= 0x40000000; fb->fb_bus_address = fbinfo.base; @@ -1087,6 +1096,7 @@ static int bcm2708_fb_probe(struct platform_device *dev) ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_NUM_DISPLAYS, &num_displays, sizeof(u32)); + num_displays = le32_to_cpu(num_displays); /* If we fail to get the number of displays, or it returns 0, then * assume old firmware that doesn't have the mailbox call, so just @@ -1149,19 +1159,23 @@ static int bcm2708_fb_probe(struct platform_device *dev) for (i = 0; i < num_displays; i++) { struct bcm2708_fb *fb = &fbdev->displays[i]; - fb->display_settings.display_num = i; + fb->display_settings.display_num = cpu_to_le32(i); fb->dev = dev; fb->fb.device = &dev->dev; fb->fbdev = fbdev; - fb->gpu.base = gpu_mem.base; - fb->gpu.length = gpu_mem.length; + fb->gpu.base = le32_to_cpu(gpu_mem.base); + fb->gpu.length = le32_to_cpu(gpu_mem.length); if (fbdev->firmware_supports_multifb) { ret = rpi_firmware_property(fw, RPI_FIRMWARE_FRAMEBUFFER_GET_DISPLAY_SETTINGS, &fb->display_settings, GET_DISPLAY_SETTINGS_PAYLOAD_SIZE); + fb->display_settings.display_num = le32_to_cpu(fb->display_settings.display_num); + fb->display_settings.width = le32_to_cpu(fb->display_settings.width); + fb->display_settings.height = le32_to_cpu(fb->display_settings.height); + fb->display_settings.depth = le32_to_cpu(fb->display_settings.depth); } else { memset(&fb->display_settings, 0, sizeof(fb->display_settings));