karo: use lldiv() for 64bit division
authorLothar Waßmann <LW@KARO-electronics.de>
Tue, 22 Sep 2015 11:56:37 +0000 (13:56 +0200)
committerLothar Waßmann <LW@KARO-electronics.de>
Tue, 22 Sep 2015 11:56:37 +0000 (13:56 +0200)
board/karo/tx28/flash.c
board/karo/tx53/flash.c
board/karo/tx6/flash.c
drivers/video/ipu_common.c

index 4aa3bc9..7833f79 100644 (file)
@@ -407,7 +407,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        size_t size = 0;
        void *addr = NULL;
        struct mx28_fcb *fcb;
-       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+       unsigned long mtd_num_blocks = lldiv(mtd->size, mtd->erasesize);
 #ifdef CONFIG_ENV_IS_IN_NAND
        unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
        unsigned long env_end_block = env_start_block +
@@ -420,7 +420,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        unsigned long fw_num_blocks;
        int fw1_skip, fw2_skip;
        unsigned long extra_blocks = 0;
-       size_t max_len1, max_len2;
+       u64 max_len1, max_len2;
        struct mtd_device *dev;
        struct part_info *part_info;
        struct part_info *redund_part_info;
@@ -544,12 +544,12 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                uboot_part, ret);
                        return ret;
                }
-               fw1_start_block = part_info->offset / mtd->erasesize;
+               fw1_start_block = lldiv(part_info->offset, mtd->erasesize);
                max_len1 = part_info->size;
                if (size == 0)
-                       fw_num_blocks = max_len1 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len1, mtd->erasesize);
        } else {
-               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len1 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        }
 
        if (redund_part) {
@@ -560,26 +560,26 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                redund_part, ret);
                        return ret;
                }
-               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               fw2_start_block = lldiv(redund_part_info->offset, mtd->erasesize);
                max_len2 = redund_part_info->size;
                if (fw2_start_block == fcb_start_block) {
                        fw2_start_block++;
                        max_len2 -= mtd->erasesize;
                }
                if (size == 0)
-                       fw_num_blocks = max_len2 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len2, mtd->erasesize);
        } else if (fw2_set) {
-               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len2 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        } else {
                max_len2 = 0;
        }
 
        fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
-                               max_len1 / mtd->erasesize);
+                               lldiv(max_len1, mtd->erasesize));
        if (fw1_skip < 0) {
-               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%llu\n",
                        fw_num_blocks, fw1_start_block,
-                       fw1_start_block + max_len1 / mtd->erasesize - 1);
+                       fw1_start_block + lldiv(max_len1, mtd->erasesize) - 1);
                if (uboot_part) {
 #ifdef CONFIG_ENV_IS_IN_NAND
                        if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
@@ -606,11 +606,11 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                fw2_start_block = fw1_end_block + 1;
        if (fw2_start_block > 0) {
                fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
-                                       max_len2 / mtd->erasesize);
+                                       lldiv(max_len2, mtd->erasesize));
                if (fw2_skip < 0) {
-                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%llu\n",
                                fw_num_blocks, fw2_start_block,
-                               fw2_start_block + max_len2 / mtd->erasesize - 1);
+                               fw2_start_block + lldiv(max_len2, mtd->erasesize) - 1);
                        if (redund_part) {
                                printf("Increase the size of the '%s' partition or use a different partition\n",
                                        redund_part);
index 76e994c..2d5bcde 100644 (file)
@@ -111,7 +111,8 @@ static struct mx53_fcb *create_fcb(void *buf, int fw1_start_block,
        fcb->fw1_start_page = fw1_start_block * sectors_per_block;
        pr_fcb_val(fcb, fw1_start_page);
 
-       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+       if (fw2_start_block != 0 &&
+               fw2_start_block < lldiv(mtd->size, mtd->erasesize)) {
                fcb->fw2_start_page = fw2_start_block * sectors_per_block;
                pr_fcb_val(fcb, fw2_start_page);
        }
@@ -158,8 +159,6 @@ static int write_fcb(void *buf, int block)
                return 0;
        }
 
-       printf("Erasing FCB block %08x..%08x\n", block * mtd->erasesize,
-               block * mtd->erasesize + mtd->erasesize - 1);
        if (doit) {
                ret = nand_erase(mtd, block * mtd->erasesize, mtd->erasesize);
                if (ret) {
@@ -266,7 +265,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        size_t size = 0;
        void *addr = NULL;
        struct mx53_fcb *fcb;
-       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+       unsigned long mtd_num_blocks = lldiv(mtd->size, mtd->erasesize);
 #ifdef CONFIG_ENV_IS_IN_NAND
        unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
        unsigned long env_end_block = env_start_block +
@@ -279,7 +278,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        unsigned long fw_num_blocks;
        int fw1_skip, fw2_skip;
        unsigned long extra_blocks = 0;
-       size_t max_len1, max_len2;
+       u64 max_len1, max_len2;
        struct mtd_device *dev;
        struct part_info *part_info;
        struct part_info *redund_part_info;
@@ -403,12 +402,12 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                uboot_part, ret);
                        return ret;
                }
-               fw1_start_block = part_info->offset / mtd->erasesize;
+               fw1_start_block = lldiv(part_info->offset, mtd->erasesize);
                max_len1 = part_info->size;
                if (size == 0)
-                       fw_num_blocks = max_len1 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len1, mtd->erasesize);
        } else {
-               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len1 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        }
 
        if (redund_part) {
@@ -419,26 +418,26 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                redund_part, ret);
                        return ret;
                }
-               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               fw2_start_block = lldiv(redund_part_info->offset, mtd->erasesize);
                max_len2 = redund_part_info->size;
                if (fw2_start_block == fcb_start_block) {
                        fw2_start_block++;
                        max_len2 -= mtd->erasesize;
                }
                if (size == 0)
-                       fw_num_blocks = max_len2 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len2, mtd->erasesize);
        } else if (fw2_set) {
-               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len2 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        } else {
                max_len2 = 0;
        }
 
        fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
-                               max_len1 / mtd->erasesize);
+                               lldiv(max_len1, mtd->erasesize));
        if (fw1_skip < 0) {
-               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%llu\n",
                        fw_num_blocks, fw1_start_block,
-                       fw1_start_block + max_len1 / mtd->erasesize - 1);
+                       fw1_start_block + lldiv(max_len1, mtd->erasesize) - 1);
                if (uboot_part) {
 #ifdef CONFIG_ENV_IS_IN_NAND
                        if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
@@ -465,11 +464,11 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                fw2_start_block = fw1_end_block + 1;
        if (fw2_start_block > 0) {
                fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
-                                       max_len2 / mtd->erasesize);
+                                       lldiv(max_len2, mtd->erasesize));
                if (fw2_skip < 0) {
-                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%llu\n",
                                fw_num_blocks, fw2_start_block,
-                               fw2_start_block + max_len2 / mtd->erasesize - 1);
+                               fw2_start_block + lldiv(max_len2, mtd->erasesize) - 1);
                        if (redund_part) {
                                printf("Increase the size of the '%s' partition or use a different partition\n",
                                        redund_part);
@@ -491,7 +490,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        fail_if_overlap(fw1, env, "FW1", "Environment");
 #endif
        if (fw2_set) {
-               fail_if_overlap(fw2, fcb, "FW2", "FCB");
+               fail_if_overlap(fcb, fw2, "FCB", "FW2");
 #ifdef CONFIG_ENV_IS_IN_NAND
                fail_if_overlap(fw2, env, "FW2", "Environment");
 #endif
index d57c994..7d0ddc6 100644 (file)
@@ -281,7 +281,8 @@ static struct mx6_fcb *create_fcb(void *buf, int fw1_start_block,
        pr_fcb_val(fcb, fw1_start_page);
        pr_fcb_val(fcb, fw1_sectors);
 
-       if (fw2_start_block != 0 && fw2_start_block < mtd->size / mtd->erasesize) {
+       if (fw2_start_block != 0 &&
+               fw2_start_block < lldiv(mtd->size, mtd->erasesize)) {
                fcb->fw2_start_page = fw2_start_block * fcb->sectors_per_block;
                fcb->fw2_sectors = fcb->fw1_sectors;
                pr_fcb_val(fcb, fw2_start_page);
@@ -449,7 +450,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        size_t size = 0;
        void *addr = NULL;
        struct mx6_fcb *fcb;
-       unsigned long mtd_num_blocks = mtd->size / mtd->erasesize;
+       unsigned long mtd_num_blocks = lldiv(mtd->size, mtd->erasesize);
 #ifdef CONFIG_ENV_IS_IN_NAND
        unsigned long env_start_block = CONFIG_ENV_OFFSET / mtd->erasesize;
        unsigned long env_end_block = env_start_block +
@@ -462,7 +463,7 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
        unsigned long fw_num_blocks;
        int fw1_skip, fw2_skip;
        unsigned long extra_blocks = 0;
-       size_t max_len1, max_len2;
+       u64 max_len1, max_len2;
        struct mtd_device *dev;
        struct part_info *part_info;
        struct part_info *redund_part_info;
@@ -586,12 +587,12 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                uboot_part, ret);
                        return ret;
                }
-               fw1_start_block = part_info->offset / mtd->erasesize;
+               fw1_start_block = lldiv(part_info->offset, mtd->erasesize);
                max_len1 = part_info->size;
                if (size == 0)
-                       fw_num_blocks = max_len1 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len1, mtd->erasesize);
        } else {
-               max_len1 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len1 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        }
 
        if (redund_part) {
@@ -602,26 +603,26 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                                redund_part, ret);
                        return ret;
                }
-               fw2_start_block = redund_part_info->offset / mtd->erasesize;
+               fw2_start_block = lldiv(redund_part_info->offset, mtd->erasesize);
                max_len2 = redund_part_info->size;
                if (fw2_start_block == fcb_start_block) {
                        fw2_start_block++;
                        max_len2 -= mtd->erasesize;
                }
                if (size == 0)
-                       fw_num_blocks = max_len2 / mtd->erasesize;
+                       fw_num_blocks = lldiv(max_len2, mtd->erasesize);
        } else if (fw2_set) {
-               max_len2 = (fw_num_blocks + extra_blocks) * mtd->erasesize;
+               max_len2 = (u64)(fw_num_blocks + extra_blocks) * mtd->erasesize;
        } else {
                max_len2 = 0;
        }
 
        fw1_skip = find_contig_space(fw1_start_block, fw_num_blocks,
-                               max_len1 / mtd->erasesize);
+                               lldiv(max_len1, mtd->erasesize));
        if (fw1_skip < 0) {
-               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%lu\n",
+               printf("Could not find %lu contiguous good blocks for fw image in blocks %lu..%llu\n",
                        fw_num_blocks, fw1_start_block,
-                       fw1_start_block + max_len1 / mtd->erasesize - 1);
+                       fw1_start_block + lldiv(max_len1, mtd->erasesize) - 1);
                if (uboot_part) {
 #ifdef CONFIG_ENV_IS_IN_NAND
                        if (part_info->offset <= CONFIG_ENV_OFFSET + TOTAL_ENV_SIZE) {
@@ -648,11 +649,11 @@ int do_update(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
                fw2_start_block = fw1_end_block + 1;
        if (fw2_start_block > 0) {
                fw2_skip = find_contig_space(fw2_start_block, fw_num_blocks,
-                                       max_len2 / mtd->erasesize);
+                                       lldiv(max_len2, mtd->erasesize));
                if (fw2_skip < 0) {
-                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%lu\n",
+                       printf("Could not find %lu contiguous good blocks for redundant fw image in blocks %lu..%llu\n",
                                fw_num_blocks, fw2_start_block,
-                               fw2_start_block + max_len2 / mtd->erasesize - 1);
+                               fw2_start_block + lldiv(max_len2, mtd->erasesize) - 1);
                        if (redund_part) {
                                printf("Increase the size of the '%s' partition or use a different partition\n",
                                        redund_part);
index 7ed2437..ecfec77 100644 (file)
@@ -13,6 +13,7 @@
 
 /* #define DEBUG */
 #include <common.h>
+#include <div64.h>
 #include <ipu.h>
 #include <linux/types.h>
 #include <linux/err.h>
@@ -179,10 +180,12 @@ static inline void ipu_ch_param_set_buffer(uint32_t ch, int bufNum,
 static void ipu_pixel_clk_recalc(struct clk *clk)
 {
        u32 div = __raw_readl(DI_BS_CLKGEN0(clk->id));
+       u64 parent_rate = (u64)clk->parent->rate * 16;
+
        if (div == 0)
                clk->rate = 0;
        else
-               clk->rate = (clk->parent->rate * 16) / div;
+               clk->rate = lldiv(parent_rate, div);
 }
 
 static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
@@ -190,38 +193,41 @@ static unsigned long ipu_pixel_clk_round_rate(struct clk *clk,
 {
        u32 div, div1;
        u64 tmp;
+
        /*
         * Calculate divider
         * Fractional part is 4 bits,
         * so simply multiply by 2^4 to get fractional part.
         */
        tmp = (u64)clk->parent->rate * 16;
-       div = tmp / rate;
+       div = lldiv(tmp, rate);
 
        if (div < 0x10)            /* Min DI disp clock divider is 1 */
                div = 0x10;
-       if (div & ~0xFEF)
+       if (div & ~0xFEF) {
                div &= 0xFF8;
-       else {
+       else {
                div1 = div & 0xFE0;
-               if ((tmp/div1 - tmp/div) < rate / 4)
+
+               if ((lldiv(tmp, div1) - lldiv(tmp, div)) < rate / 4)
                        div = div1;
                else
                        div &= 0xFF8;
        }
-       tmp /= div;
+       do_div(tmp, div);
 #if 1
        debug("%s: requested rate: %lu.%03luMHz parent_rate: %lu.%03luMHz actual rate: %llu.%03lluMHz div: %u.%u\n", __func__,
                rate / 1000000, rate / 1000 % 1000,
                clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
-               tmp / 1000000, tmp / 1000 % 1000, div / 16, div % 16);
+               lldiv(tmp, 1000000), lldiv(tmp, 1000) % 1000, div / 16, div % 16);
 #endif
        return tmp;
 }
 
 static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
 {
-       u32 div = ((u64)clk->parent->rate * 16) / rate;
+       u64 parent_rate = (u64)clk->parent->rate * 16;
+       u32 div = lldiv(parent_rate, rate);
 
        debug("%s: parent_rate: %lu.%03luMHz actual rate: %lu.%03luMHz div: %u.%u\n", __func__,
                clk->parent->rate / 1000000, clk->parent->rate / 1000 % 1000,
@@ -231,8 +237,7 @@ static int ipu_pixel_clk_set_rate(struct clk *clk, unsigned long rate)
 
        /* Setup pixel clock timing */
        __raw_writel((div / 16) << 16, DI_BS_CLKGEN1(clk->id));
-
-       clk->rate = ((u64)clk->parent->rate * 16) / div;
+       clk->rate = lldiv(parent_rate, div);
        debug("%s: pix_clk=%lu.%03luMHz\n", __func__,
                clk->rate / 1000000, clk->rate / 1000 % 1000);
        return 0;